繁体   English   中英

试图弄清楚如何在获得所有解决方案后停止这个 n 皇后方法,有什么方法可以解决这个问题?

[英]Trying to figure out how to make this n queens method stop once it gets all all of the solutions, what are some ways to approach this problem?

我正在使用堆栈而不是递归调用来解决好的 ol' N-queens 问题,以便找到 N Queens 的解决方案总数。 我相信我拥有的程序可以工作,除了我无法弄清楚如何跳出找到解决方案的循环。 go 有什么方法可以解决这个问题?

这是我的一门计算机科学课程,使用 java。 我已经尝试了我朋友的建议,以在当前行位于板内时暂时设置条件,但这会导致在找到解决方案之前停止解决方案搜索的一些问题。 我还尝试在堆栈大小为 1 时跳出循环,但这仅在 N = 4 时有效,不适用于较大的 N 值,该程序也可能不适用于 N > 4,尚未测试还没有。

EmptyStackException 当 N = 5 并且当

Exception in thread "main" java.util.EmptyStackException
    at java.base/java.util.Stack.peek(Stack.java:102)
    at java.base/java.util.Stack.pop(Stack.java:84)
    at Assignment22.stacker(Assignment22.java:61)
    at Assignment22.main(Assignment22.java:11)
// gets number of solutions to N Queens
public static int stacker(boolean[][] board, int numQueens) {
        Stack<Integer> queensPos = new Stack<Integer>();
        int row = 0;
        int col = 0;
        int numSolutions = 0;

        // need to figure out how to tell program to
        // go back to previous row and remove queen
        // if col = 3 and row = 1, queen will always be placed there
        // however if queen is placed there, there is no solution
        // if row being worked on is in the board
        while (row <= board.length) {
            // if you have no more queens to place
            if (numQueens == 0) {
                // you have a solution
                for (int i = 0; i < queensPos.size(); i++) {
                    System.out.println(queensPos.get(i));
                }
                numSolutions += 1;
                // go back to last row
                row -= 1;
                // remove queen
                col = queensPos.pop();
                board[row][col] = false;
                // go back one row
                //row -= 1;
                numQueens += 1;
                col += 1;

            } else {
                // if there is a conflict and column is within board
                if (IsConflictPresent(board, row, col) && col < board[row].length - 1) {
                    // shift queen rightward
                    col += 1;
                // if column is out of board
                } else if (IsConflictPresent(board, row, col) && col == board[row].length - 1) {
                    // look at value of column, if it is at end of board
                    // go back to previous row
                    // looks at top of stack
                    col = queensPos.pop();  // <- EmptyStackException occurs here

                    if (row > 0) {
                        row -= 1;
                    }
                    board[row][col] = false;
                    numQueens += 1;
                    // attempt to solve problem where queen at end of 2nd row would keep getting placed
                    // appears to be working
                    if (!(col < board[row].length - 1)) {
                        col = queensPos.pop();

                        row -= 1;
                        board[row][col] = false;
                        numQueens += 1;
                        col += 1;
                    } else {
                        col += 1;
                    }
                } else  {
                // if queen can be placed
                    // place queen at row, col
                    board[row][col] = true;
                    queensPos.push(col);
                    numQueens -= 1;
                    // move to next row
                    row += 1;
                    // start at beginning of row
                    col = 0;

                    // when the below code is put in, EmptyStackException occurs when numQueens = 5
                    if (queensPos.size() == 1) {
                        row -= 1;
                        col = queensPos.pop();
                        numQueens += 1;
                    } 

                }
            }

        }
        return numSolutions;
    }

public static boolean IsConflictPresent(boolean[][] boardToCheck, int row, int col) {

        // figure out how to check one diagonal

        int i,j;
        int N = boardToCheck.length;
        // use 4 for loops
        // check on left side of row specified
        for (i = 0; i <= col; i++) {
            if (boardToCheck[row][i])
            {
                return true;
            }
        }

        for (i = 0; i < boardToCheck[row].length - 1; i++) {
            if (boardToCheck[i][col]) {
                return true;
            }
        }

        // to check diagonal, start at row 0 column 0, go up to row and column specified
        // upper diag on left side

        for (i = row, j = col; i >= 0 && j >= 0; i--, j--) {
            if (boardToCheck[i][j]) {
                return true;
            }
        }
        // upper right diagonal check
        for (i = row, j = col; i >= 0 && j < N; i--, j++) {
            if (boardToCheck[i][j]) {
                return true;
            }
        }
        // lower diagonal on left side
        for (i = row, j = col; j >= 0 && i < N; i++, j--) {
            if (boardToCheck[i][j]) {
                return true;
            }
        }
        // lower diagonal on right side
        for (i = row, j = col; j < N && i < N; i++, j++) {
            if (boardToCheck[i][j]) {
                return true;
            }
        }


        return false;
    }

我希望程序最终会停止,但我得到一个无限循环,并且根据我尝试过的修复,ArrayIndexOutOfBoundsException 或 EmptyStackException

我发现的主要问题是当 N > 4 时,皇后不能放在最后一列的任何位置,所以我修改了这个条件

if (!(col < board[row].length - 1)) {
                        col = queensPos.pop();

                        row -= 1;
                        board[row][col] = false;
                        numQueens += 1;
                        col += 1;
                    } else {
                        col += 1;
                    }

并添加了 row > 0 的条件

最终堆垛机方法:

    public static int stacker(boolean[][] board, int numQueens) {
        Stack<Integer> queensPos = new Stack<Integer>();
        int row = 0;
        int col = 0;
        int numSolutions = 0;
        int colLastUsed = 0;
        // need to figure out how to tell program to
        // go back to previous row and remove queen
        // if col = 3 and row = 1, queen will always be placed there
        // however if queen is placed there, there is no solution
        // if row being worked on is in the board
        while (row <= board.length) {
            // if you have no more queens to place
            if (numQueens == 0) {
                // you have a solution
                for (int i = 0; i < board.length; i++) {
                    for (int j = 0; j < board[i].length; j++) {
                        if (board[i][j]) {
                            System.out.print("Q");
                        } else {
                            System.out.print("*");
                        }
                    }
                    System.out.println();
                }
                System.out.println();
                /*for (int i = 0; i < queensPos.size(); i++) {
                    System.out.print(queensPos.get(i) +" ");
                }
                System.out.println();*/
                numSolutions += 1;
                // go back to last row
                row -= 1;
                // remove queen
                col = queensPos.pop();
                board[row][col] = false;
                // go back one row
                //row -= 1;
                numQueens += 1;
                if (col < board.length - 1) {
                    // add one to col if it is not at end of row
                    col += 1;
                } else {
                    // go back another row
                    row -= 1;
                    col = queensPos.pop();

                    board[row][col] = false;

                    numQueens += 1;
                    col += 1;
                }
            // if there is a conflict and column is within board

            } else {
                if (col == board[row].length && row == 0) {
                    break;
                } else if (IsConflictPresent(board, row, col) && col < board[row].length - 1) {
                    // shift queen rightward
                    col += 1;
                    // if column is out of board
                } else if (IsConflictPresent(board, row, col) && col == board[row].length - 1) {
                    // look at value of column, if it is at end of board
                    // go back to previous row
                    // looks at top of stack
                    col = queensPos.pop();

                    if (row > 0) {
                        row -= 1;
                    }
                    board[row][col] = false;
                    numQueens += 1;
                    // attempt to solve problem where queen at end of 2nd row would keep getting placed
                    // appears to be working
                    if (!(col < board[row].length - 1) && row > 0) {
                        col = queensPos.pop();

                        row -= 1;
                        board[row][col] = false;
                        numQueens += 1;
                        col += 1;
                    } else {
                        col += 1;
                    }
                    // how to check to see if the column number you used
                } else {
                    // if queen can be placed
                    // place queen at row, col
                    board[row][col] = true;
                    queensPos.push(col);
                    numQueens -= 1;
                    // move to next row
                    row += 1;
                    // start at beginning of row
                    col = 0;

                }
            }

        }
        return numSolutions;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM