【问题标题】:Simulated Annealing N Queens Probability Forumula模拟退火 N 皇后概率公式
【发布时间】:2013-03-03 19:22:31
【问题描述】:

我在使用模拟退火算法来解决 n 皇后问题时遇到了一些问题。基本上,我让它寻找更好的更多,它工作得很好,但是我运行一个公式来检查它是否应该采取“坏”的举动。据我了解,公式是 e^(板状态计算变化)/CurrentTemperature。该数字应与随机双精度或浮点数进行比较,如果随机数大于等式,则算法应采取“坏”举动。我遇到的问题是公式总是非常接近 1 或超过 1。这是我的一些代码(让我知道是否应该提供更多):

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;
                }
            }
        }

    }

我尝试了很多方法,例如将检查变量设为负数或取棋盘状态之间差异的绝对值。此外,被调用的计算函数基本上是扫描棋盘并返回有多少皇后发生冲突,这是一个 int。让我知道是否需要更多说明。谢谢

【问题讨论】:

  • Here 是我在 Java 中的模拟退火实现,它也适用于 N 个皇后和 many more advanced use cases。也许它有帮助。它适用于多个分数级别(分数由多于 1 的两倍组成)。
  • @GeoffreyDeSmet 您好,Geoffrey,您能否再次发送您的代码。我无法打开您的链接。
  • @GeoffreyDeSmet 谢谢,这个新链接有效:)

标签: java n-queens simulated-annealing


【解决方案1】:

也许OptaPlanner 的文档中这张图片中的公式和示例也有帮助:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多