【问题标题】:Recursive N-Queens : missing solutions递归 N 皇后:缺少解决方案
【发布时间】:2016-09-30 21:15:31
【问题描述】:

我写了一个 N-Queens 谜题的 Java 小算法(带有一个 c*c 棋盘)。您将在下面找到我的递归方法的代码。

它没有找到所有的解决方案。

我的功能是什么

这个想法是,在 main 方法中,第一次调用我的函数,给它最大数量的皇后,直到找到解决方案,没有任何皇后的棋盘和这些新皇后的坐标:x=0,y =0。

该函数将通过棋盘。对于每个方格,它测试是否可以放置皇后(0;0)(即:没有威胁)。女王(0;0)可以放置吗?好吧,我们这样做(修改棋盘)并调用函数(递归调用)。这个递归调用是通过“皇后的最大数量 - 1”、修改后的棋盘和“新皇后的 y + 1”(稍微复杂一点)来完成的。

找到 n=4 和 c=4 的解决方案(通常有两个解决方案...!)

&&Q&

问&&&

&&&Q

&Q&&

我的函数的最新代码

private static void setQueen(int nb_queens, ArrayList<ArrayList<Boolean>> chessboard, int x, int y, ArrayList<ArrayList<ArrayList<Boolean>>> solutions) {
    if (nb_queens == 0) { // If there isn't any queen remaining, it means we found a solution
        drawChessboard(chessboard);
        solutions.add(chessboard);
    }

    for(int i = x; i < chessboard.size(); i++) {
        for (int z = y; z < chessboard.get(i).size(); z++) {
            if(!canBePlaced(i, z, chessboard)) {
                chessboard.get(z).set(i, true); // On peut donc placer cette reine(x;y) et on le fait
                setQueen(nb_queens-1, chessboard, i+1, 0, solutions);
                chessboard.get(z).set(i, false);
            }
        }
    }

}

旧代码

private static void setQueen(int nb_queens, ArrayList<ArrayList<Boolean>> chessboard, int x, int y, ArrayList<ArrayList<ArrayList<Boolean>>> solutions) {
    if (nb_queens == 0) {
        drawChessboard(chessboard); // Il n'y a plus de reine à placer => on dessine cette solution
        solutions.add(chessboard);
    }

    for(int i = x; i < chessboard.size(); i++) {
        for (int z = y; z < chessboard.get(i).size(); z++) {
            if(!isAQueenAlreadyPresent(i, z, chessboard)) {
                chessboard.get(z).set(i, true); // On peut donc placer cette reine(x;y) et on le fait
                setQueen(nb_queens-1, chessboard, i, (z+1 >= WIDTH) ? 0 : z+1, solutions);
                chessboard.get(z).set(i, false);
            }
        }
    }

}

【问题讨论】:

  • 它是否找到任何解决方案?结果是什么?另外,放isAQueenAlreadyPresent(i, z, chessboard),应该没问题,但谁知道呢。此外,同时使用递归和迭代并不是很有用...
  • 我编辑了 OP 以显示结果 :)
  • 啊,是的,现在我明白为什么递归和迭代了。但实际上似乎缺少很多结果,不是还有很多吗?像,这些解决方案的对称性?像 &&Q &&& &Q& 与你的第一个结果对称。
  • 是的,缺少很多解决方案。我不明白为什么。我不认为这是因为isQueenAlreadyPresent
  • 可以添加这个函数的代码吗?

标签: java recursion n-queens


【解决方案1】:

哦,对了,那是因为你如何递归调用,你在做setQueen(nb_queens-1, chessboard, i, z+1, solutions);z+1 部分是问题所在,它总是会在您放置在全局板上的第一个皇后的右侧找到解决方案。

编辑:啊,你之前找到了,很好。

因此,问题在于 for 循环充当 if(z&gt;=y),因为它从 y 开始。 i = x(读第一行)时没问题,但i &gt; x 时不行。因此,一个简单的解决方法是将y = ( i == x ) ? y : 0 放在第一个for 循环之后。

还有更简洁的解决方案,比如使用单个索引遍历整个棋盘。

我还建议您将参数重命名为 startX 和 startY(而不是 x 和 y,您可以在循环中使用 x 和 y 更清晰)。

Edit2:由于游戏规则,同一行永远不会有皇后,所以你可以像setQueen(nb_queens-1, chessboard, i+1, 0, solutions);i+1,因为你直接从下一行开始)进行递归调用。因此,您甚至可以从setQueen 方法中删除int y 参数,并始终从0 开始z loop

【讨论】:

  • 如果我写:int new_z = (z+1 &gt;= WIDTH) ? 0 : z+1;,然后使用new_z(而不是z)进行递归调用,似乎n=4 和c=4 仍然缺少一些解决方案.我应该找到 2 个解决方案,而我只有一个。你知道为什么吗?
  • 您可以通过 for(int i = 0; ..for (int z = 0;.. 轻松解决问题,因为您非常丑陋,并且复杂度为 n^3。 (写一个更好的解决方案)
  • 所以你认为我的i,z = a_parameter 不能保留在我的两个for 中?
  • 是的,你可以,但这需要我在编辑中编写的其他解决方案。
  • 我编辑了我的 OP(以显示新代码)。我可以指出您的登录信息,因为您帮助了我吗?我的更改是:递归调用中的“i+1, 0”并且我删除了y = ( i == x ) ? y : 0
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-23
  • 2019-05-11
  • 2021-11-10
  • 1970-01-01
  • 1970-01-01
  • 2013-07-22
  • 2015-10-25
相关资源
最近更新 更多