N queens算法错误以及如何打印所有解决方案

时间:2015-09-21 22:31:47

标签: java algorithm n-queens

处理N皇后问题(非递归和堆栈)并有两个相当具体的问题:

我的" notSafe"方法,检查同一行/列中是否有皇后和对角线作为另一个皇后是否真的有效。我无法发现逻辑错误,这可能是由于另一种方法"完成",这可能无法正确回溯。

另外,第二个问题:有关如何打印所有解决方案的任何想法?也许有一些提示让我开始。

import java.util.Stack;

public class Test1 {

static Stack<Integer> s = new Stack<Integer>();
static int topRow = 0;
static int currentRow = 0;
static int row = 0;
static int n = 8;


public static void main(String args[]) {

    finish(n);

}

public static void finish(int n) {
    placeQueen();
    placeQueen();

    boolean success = false;
    while (success != true) {

        if (notSafe() == true && s.empty() == false) {
            int c = 1;

            do {

                if (c <= n) {
                    s.pop();
                    row--;
                    c++;
                    s.push(c);
                    row++;
                } else if (c <= n && s.size() == 0) {
                    c++;
                    s.push(c);
                    row++;

                } else {
                    c = 1;
                    s.pop();

                }

            } while (notSafe() == true);

        } else if (s.size() == n && notSafe() == false) {
            display();
            break;
        } else {
            placeQueen();

        }

    }
}

public static boolean notSafe() {
    boolean status = false;
    int top = s.size()-1;

    topRow = row;
    int temp = row;
    currentRow = temp - 1;

    if (s.size() > 1) {

        for (int m = top; m >= 1; m--) {
            int x = (Integer) s.get(top);
            int y = (Integer) s.get(m - 1);
            if ((x == y) || x - y == currentRow || x + y == currentRow) {

                status = true;

            }
        }
    }

    return status;
}

public static void placeQueen() {

    s.push(1);
    row++;

}
//======Display=======//
public static void display() {
    int z = 0;
    while (z != s.size()) {

        int x = (Integer) s.pop();
        for (int y = 1; y <= n; y++) {

            if (x != (y)) {
                System.out.print("-");

            } else
                System.out.print("q");
        }
        System.out.print("\n");
    }
}

}

1 个答案:

答案 0 :(得分:0)

这里要指出几个问题:

  • 您似乎在前2列中的第1行放置了两个女王。这将使解决方案非法(并假设n> 1)
  • 您不需要继续测试已经放置的皇后:只需检查您要用于下一列的行是否与之前的任何皇后位于同一行(更改方法以接受行)测试)。

如果您遵循这些建议,那么您可以简化为:

private boolean rowIsSafe(int testRow) {
    for (int col = 0; col < stack.size(); col++) {
       if (stack.get(col) == testRow)
           return false;
       if (Maths.abs(testRow - stack.get(col)) == stack.size() - col)
           return false;
    }
    return true;
}

或者,在Java 8中:

IntStream.range(0, stack.size()).noneMatch(col -> stack.get(col) == testRow
    || Maths.abs(testRow - stack.get(col)) == stack.size() - col)

打印出所有解决方案只是意味着一旦你找到解决方案就不会停止(即break):打印它,弹出它并继续前进。