Simulated Annealing N Queens Probability Forumula - java

I am having some trouble with a simulated annealing algorithm to solve the n queens problem. Basically, I have it look for a better more, which works fine, but then I run a formula to check and see if it should take a "bad" move or not. From my understanding, the formula is e^(change in board state calculation)/CurrentTemperature. This number should be compared against a random double or float, if the random number is greater than the equation, the algorithm should take the "bad" move. The problem that I am getting is that the formula is always either REALLY close to 1 or over 1. Here some of my code (let me know if more should be provided):
temperature = n*100; //initializes starting temperature
currentTemp = n*100;
int cooldown = n*2; //initializes cool down temperature
float examine = 0; //this is the change in board calculation
int cost = 1;
boolean betterMove = false;
queen = new int[n];
int[][] board = graph; // generates a board of n size
float ran = 0; //random float to compare to
double compareAgainst = 0; //formula variable
cost = calculate(board, n); //calculates the cost
while (cost > 0 && currentTemp > 0)
{
// chooses a random queen to move that has a heuristic higher than zero
int Q = rand.nextInt(n);
while (queen[Q] == 0)
Q = rand.nextInt(n);
betterMove = false;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (board[i][j] == 1 && j == Q)
{
while (!betterMove)
{
int move = i;
while (move == i)
move = rand.nextInt(n); //pick a random move
tempBoard[i][j] = 0; //erase old position
tempBoard[move][j] = 1; //set new position
examine = calculate(tempBoard, n) - calculate(board, n); //calculates the difference between the change in boards
ran = rand.nextFloat(); //generates random number to compare against
compareAgainst = Math.pow(Math.E, (-examine / currentTemp)); //formula out of the book, basically is e^(change in board state divided by currentTemp)
if (calculate(tempBoard, n) < calculate(board, n)) //if this is a better move
{
for (int a = 0; a < n; a++)
for (int b = 0; b < n; b++)
board[a][b] = tempBoard[a][b]; //set it to the board
cost = calculate(board, n);
currentTemp -= cooldown; //cool down the temperature
betterMove = true;
}
else if(calculate(tempBoard,n) >= calculate(board,n)) //if this is a worse move
{
if(verbose == 1) //outputs whether or not this is a bad move and outputs function value and random float for simulated annealing purposes
{
System.out.println("This is a worse move");
System.out.println("The numbers for Simulated Annealing:");
System.out.println("Random number = " + ran);
System.out.println("Formula = " + compareAgainst);
System.out.println("Examine = " + examine);
}
if(ran > compareAgainst) //if the random float is greater than compare against, take the bad move
{
for (int a = 0; a < n; a++)
for (int b = 0; b < n; b++)
board[a][b] = tempBoard[a][b]; //take the move
cost = calculate(board, n);
currentTemp-= cooldown;
betterMove = true;
}
else //if not, do not take the move
{
for (int a = 0; a < n; a++)
for (int b = 0; b < n; b++)
tempBoard[a][b] = board[a][b];
}
currentTemp-= cooldown;
betterMove = true;
}
}
}
i = n;
j = n;
}
}
}
}
I have tried a number of things such as making the examine variable negative or taking the absolute value of the difference between board states. Also, the calculate function that is being called basically scans the board and returns back how many queens are in conflict, which is an int. Let me know if more clarification is needed. Thanks

Maybe the formula and examples in this image from OptaPlanner's docs help too:

Related

Is there something wrong with my Magic Square Code?

A brief explanation: With the code below it will make a randomly generated Square and some code below would make sure that it was a Magic Square, in which the sum of the elements in each row, column, and the two diagonals are the same value.
My teacher said at maximum it should take three minutes to generate a magic square. So all I ask is there anything that can be done to improve or fix this code, please?
import java.util.ArrayList;
import java.util.Random;
class Main {
public static void main(String[] args) {
int size = 9;
int N = 3;
boolean result = true;
ArrayList<Integer> list = new ArrayList<Integer>(size);
int[][] mat = new int[N][N];
while (result) {
for (int i = 1; i <= size; i++) {
list.add(i);
}
Random rand = new Random();
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
int index = rand.nextInt(list.size());
System.out.print(list.remove(index)+" ");
}
System.out.println();
}
System.out.println();
// Checking process
// sumd1 and sumd2 are the sum of the two diagonals
int sumd1 = 0, sumd2 = 0;
for (int i = 0; i < N; i++) {
// (i, i) is the diagonal from top-left -> bottom-right
// (i, N - i - 1) is the diagonal from top-right -> bottom-left
sumd1 += mat[i][i];
sumd2 += mat[i][N - 1 - i];
}
// if the two diagonal sums are unequal then it is not a magic square
if (sumd1 != sumd2)
result = false;
// calculating sums of Rows and columns and checking if they are equal to each other,as well as equal to diagonal sum or not
for (int i = 0; i < N; i++) {
int rowSum = 0, colSum = 0;
for (int j = 0; j < N; j++) {
rowSum += mat[i][j];
colSum += mat[j][i];
}
if (rowSum != colSum || colSum != sumd1)
result=false;
}
result = true;
}
}
}
Trying with random numbers to coincidentally find a solution is deadly slow.
If you have the numbers 1 to 9, its entire sum 1+2+3+...+8+9 is 9*(1+9)/2 = 45.
As you have 3 rows and 3 colums, a row and column must sum upto 45/3 = 15.
Now that should restrict the number of possibilities.
So you must build in some intelligence in the code. Avoid random numbers as they do not even guarantee you'll find a solution in hundred years.
If you already treated recursion, that would be the easiest way to try all possibly valid combinations.
If you already treated Set, a BitSet maybe might be useful for a row, column or diagonal.
If you find it hard to code walking through all possibilities, you might hold the 2 dimensional matrix in a 1 dimensional array int[N*N], and have N (rows) + N (columns) + 2 (diagonals) arrays of N indices.
And of course I will not spoil your fun and satisfaction finding a smart solution.
Work it out on paper first.

Finding Similar Birthday through structure data

Hey guys I am trying to get the number of people who have the same birthday but this solution isn't working.This program is showing 0.0% .Please help me ...!.
public double calculate(int size, int count) {
int matches = 0;//initializing an integer variable
boolean out = false;
List<Integer> days=new ArrayList<Integer>();// creating arraylist name days of type int
for (int j = 0; j <count; j++) {
for (int i = 0; i < size; i++) {// initializing for loop till less than size
Random rand = new Random(); // creating an object of random function
int Brday = rand.nextInt(364) + 0;//initializing the limit of randomc number chozen
days.add(Brday); //adding values to arraylist
}
for (int l = 0; l < size; l++) {
int temp = l;//assigning value of l to a variable
for (int k = l + 1; k < size; k++) {
if (days.get(k) == temp) {// check statement to check values are same
matches++;//incrementing variable
out = true;
mOut.print("Count does have same birthday" + matches);
break;
} else {
mOut.print("does not have same birthday");
}
}
if (out) {
out = false;
break;
}
}
}
double prob = (double) matches / count;
mOut.print("The probability for two students to share a birthday is " + prob*100 + ".");
return prob;//returning double value of the function
}
Actually, you get either 0 percent or 100 percent with your code. Try invoking it with calculate(100, 100) if you want to see.
There are two things that are wrong in this code. First, if you run the simulation more than once (count > 1) then you never clear the list of birthdays before the second iteration.
Your method should begin with:
public double calculate(int size, int count) {
int matches = 0;
boolean out = false;
List<Integer> days;
for (int j = 0; j <count; j++) {
days = new ArrayList<Integer>();
Secondly, you're not comparing two birthdays but you're comparing a birthday to the index in the list.
This line:
int temp = l;//assigning value of l to a variable
Should read:
int temp = days.get(l); // Remember the birthday at index l
With those changes you'll get a much better result.

Calculate factorial of 50 using array only in java

I'm a total beginner of java.
I have a homework to write a complete program that calculates the factorial of 50 using array.
I can't use any method like biginteger.
I can only use array because my professor wants us to understand the logic behind, I guess...
However, he didn't really teach us the detail of array, so I'm really confused here.
Basically, I'm trying to divide the big number and put it into array slot. So if the first array gets 235, I can divide it and extract the number and put it into one array slot. Then, put the remain next array slot. And repeat the process until I get the result (which is factorial of 50, and it's a huge number..)
I tried to understand what's the logic behind, but I really can't figure it out.. So far I have this on my mind.
import java.util.Scanner;
class Factorial
{
public static void main(String[] args)
{
int n;
Scanner kb = new Scanner(System.in);
System.out.println("Enter n");
n = kb.nextInt();
System.out.println(n +"! = " + fact(n));
}
public static int fact(int n)
{
int product = 1;
int[] a = new int[100];
a[0] = 1;
for (int j = 2; j < a.length; j++)
{
for(; n >= 1; n--)
{
product = product * n;
a[j-1] = n;
a[j] = a[j]/10;
a[j+1] = a[j]%10;
}
}
return product;
}
}
But it doesn't show me the factorial of 50.
it shows me 0 as the result, so apparently, it's not working.
I'm trying to use one method (fact()), but I'm not sure that's the right way to do.
My professor mentioned about using operator / and % to assign the number to the next slot of array repeatedly.
So I'm trying to use that for this homework.
Does anyone have an idea for this homework?
Please help me!
And sorry for the confusing instruction... I'm confused also, so please forgive me.
FYI: factorial of 50 is 30414093201713378043612608166064768844377641568960512000000000000
Try this.
static int[] fact(int n) {
int[] r = new int[100];
r[0] = 1;
for (int i = 1; i <= n; ++i) {
int carry = 0;
for (int j = 0; j < r.length; ++j) {
int x = r[j] * i + carry;
r[j] = x % 10;
carry = x / 10;
}
}
return r;
}
and
int[] result = fact(50);
int i = result.length - 1;
while (i > 0 && result[i] == 0)
--i;
while (i >= 0)
System.out.print(result[i--]);
System.out.println();
// -> 30414093201713378043612608166064768844377641568960512000000000000
Her's my result:
50 factorial - 30414093201713378043612608166064768844377641568960512000000000000
And here's the code. I hard coded an array of 100 digits. When printing, I skip the leading zeroes.
public class FactorialArray {
public static void main(String[] args) {
int n = 50;
System.out.print(n + " factorial - ");
int[] result = factorial(n);
boolean firstDigit = false;
for (int digit : result) {
if (digit > 0) {
firstDigit = true;
}
if (firstDigit) {
System.out.print(digit);
}
}
System.out.println();
}
private static int[] factorial(int n) {
int[] r = new int[100];
r[r.length - 1] = 1;
for (int i = 1; i <= n; i++) {
int carry = 0;
for (int j = r.length - 1; j >= 0; j--) {
int x = r[j] * i + carry;
r[j] = x % 10;
carry = x / 10;
}
}
return r;
}
}
How about:
public static BigInteger p(int numOfAllPerson) {
if (numOfAllPerson < 0) {
throw new IllegalArgumentException();
}
if (numOfAllPerson == 0) {
return BigInteger.ONE;
}
BigInteger retBigInt = BigInteger.ONE;
for (; numOfAllPerson > 0; numOfAllPerson--) {
retBigInt = retBigInt.multiply(BigInteger.valueOf(numOfAllPerson));
}
return retBigInt;
}
Please recall basic level of math how multiplication works?
2344
X 34
= (2344*4)*10^0 + (2344*3)*10^1 = ans
2344
X334
= (2344*4)*10^0 + (2344*3)*10^1 + (2344*3)*10^2= ans
So for m digits X n digits you need n list of string array.
Each time you multiply each digits with m. and store it.
After each step you will append 0,1,2,n-1 trailing zero(s) to that string.
Finally, sum all of n listed string. You know how to do that.
So up to this you know m*n
now it is very easy to compute 1*..........*49*50.
how about:
int[] arrayOfFifty = new int[50];
//populate the array with 1 to 50
for(int i = 1; i < 51; i++){
arrayOfFifty[i-1] = i;
}
//perform the factorial
long result = 1;
for(int i = 0; i < arrayOfFifty.length; i++){
result = arrayOfFifty[i] * result;
}
Did not test this. No idea how big the number is and if it would cause error due to the size of the number.
Updated. arrays use ".length" to measure the size.
I now updated result to long data type and it returns the following - which is obviously incorrect. This is a massive number and I'm not sure what your professor is trying to get at.
-3258495067890909184

What exactly does int a do?

I am learning to code Java, and in a tutorial I learned to make the percentage of the percentage of wins I got. I am really confused what the integer "a" does exactly. Can someone please explain it in simple terms? (because I'm a complete newb)
double numOfGames = 10000;
double arrayNum = 1;
Random r = new Random();
int[] num = new int[(int) arrayNum]; // same as "= {0,0,0,0,0}
boolean gameResult = true;
boolean[] odds = new boolean[(int) numOfGames];
double numOfWins = 0;
for (int a = 0; a < numOfGames; a++) {
for (int i = 0; i < num.length; i++) {
num[i] = r.nextInt(100) + 1;
if (num[i] % 2 == 0) {
} else {
gameResult = false;
}
}
if (gameResult) {
odds[a] = true;
}
gameResult = true;
}
for (int i = 0; i < odds.length; i++) {
if (odds[i]) {
numOfWins++;
}
}
double perWin = (numOfWins / numOfGames) * 100;
System.out.println(perWin + " % of an array with " + arrayNum
+ " positions.");
}
}
It's a counter.
Basically it goes up by one every time that code block is run, in plain English this:
for (int a = 0; a < numOfGames; a++) {
// Do things.
}
Is like saying "Start counting at 0; Do things repeatedly until the counter reaches numOfGames".
a++ is just shorthand for a = a + 1 or "add 1 to a".
int = a is a local variable (an integer number) that increases by one in each iteration of your for loop. it simply goes from 0 to the total number of games, in this case: 10000. when it reaches the number of total games, it is discarded.

Using Recursion in java

I'm working on the Conway's game of life program. I have the first two generations of cells printed out, but I can not get anymore printed. So I decided to use recursion so multiple batches of cells can be printed. My NewCells method creates the second generation. I thought that If I were to repeat said method by returning NewCells(c) instead of c, It would print out different results, but it prints out the same batch of cells over and over again.
public class Life {
public static boolean[][] NewCells(boolean[][] c)
{
int N = 5;
int o=0;
int p=0;
int livecnt = 0; //keeps track of the alive cells surrounding cell
int store = 0; //amount of surrounding cells for each individual cell
int livestore[] = new int[N*N];
System.out.println("Next Generation");
// Checks for the amount of "*" surrounding (o,p)
for (o=0; o < N; o++)
{
for (p=0; p<N; p++)
{
for (int k=(o-1); k <= o+1; k++)
{
for (int l =(p-1); l <=p+1; l++)
{
if ( k >= 0 && k < N && l >= 0 && l < N) //for the border indexes.
{
if (!(k== o && l==p)) //so livecnt won't include the index being checked.
{
if (c[k][l] == true)
{
livecnt++;
}
}
}
}
}
livestore[store]= livecnt;
livecnt = 0;
store++;
}
}
//Prints the next batch of cells
int counter= 0;
for (int i2 = 0; i2 <N; i2++)
{
for (int j2 = 0; j2 < N; j2++)
{
if (c[i2][j2] == false)
{
if (livestore[counter] ==3)
{
c[i2][j2]=true;
System.out.print("* ");
}
else
System.out.print("- ");
}
else if (c[i2][j2] == true)
{
if (livestore[counter] ==1)
{
c[i2][j2]= false;
System.out.print("- ");
}
else if (livestore[counter] >3)
{
c[i2][j2]= false;
System.out.print("- ");
}
else
System.out.print("* ");
}
counter++;
}
System.out.println();
}
return NewCell(c);
}
/*************************************************************************************************************************************************/
public static void main(String[] args)
{
int N = 5;
boolean[][] b = new boolean[N][N];
double cellmaker = Math.random();
int i = 0;
int j = 0;
int o=0;
int p=0;
int livecnt = 0; //keeps track of the alive cells surrounding cell
int store = 0; //amount of surrounding cells for each individual cell
int livestore[] = new int[N*N];
System.out.println("First Generation:");
// Makes the first batch of cells
for ( i = 0; i < N ; i++)
{
for ( j = 0; j< N; j++)
{
cellmaker = Math.random();
if (cellmaker > 0.5) // * = alive; - = dead
{
b[i][j]=true;
System.out.print( "* ");
}
if (cellmaker < 0.5)
{ b[i][j] = false;
System.out.print("- ");
}
}
System.out.println();
}
boolean[][] newcells = new boolean[N][N];
newcells = NewCells(b);
}
}
I do not think recursion is a good idea for this application. It leads to a StackOverflowError because each generation pushes another call stack frame. Recursion, as this program uses it, has no advantage over iteration.
Instead, put the main method call to NewCells in a loop. That way, you can run as many iterations as you like, regardless of stack size.
You are not calling NewCell from within NewCell, which is how recursion works.
I'm assuming it's not a typo in your question, but rather a lack of understanding of what it is and how it works, I recommend some reading on recursion in Java.
After you understand the basics, come back here for more help!

Categories