0

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

Chase552
  • 59
  • 3
  • 8
  • [Here](https://github.com/droolsjbpm/drools-planner/blob/master/drools-planner-core/src/main/java/org/drools/planner/core/localsearch/decider/acceptor/simulatedannealing/SimulatedAnnealingAcceptor.java#L28) is my simulated annealing implementation in Java, and it works well on N queens and [many more advanced use cases](http://docs.jboss.org/drools/release/5.5.0.Final/drools-planner-docs/html_single/index.html#downloadAndRunTheExamples) too. Maybe it helps. It works for multiple score levels (where a score consists out of more then 1 just double). – Geoffrey De Smet Mar 04 '13 at 09:09
  • @GeoffreyDeSmet Hello Geoffrey, could you please send your codes again. I couldn't able to open your link. – svlzx Nov 05 '13 at 23:28
  • 1
    @svlzx [Here's my SA implementation now](https://github.com/droolsjbpm/optaplanner/blob/master/optaplanner-core/src/main/java/org/optaplanner/core/impl/localsearch/decider/acceptor/simulatedannealing/SimulatedAnnealingAcceptor.java) – Geoffrey De Smet Nov 06 '13 at 07:17
  • @GeoffreyDeSmet thanks, this new link works :) – svlzx Nov 07 '13 at 08:18

1 Answers1

1

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

enter image description here

Geoffrey De Smet
  • 26,223
  • 11
  • 73
  • 120