如何仅通过这种回溯找到第一个解决方案

发布于 2024-12-29 05:04:28 字数 1070 浏览 0 评论 0原文

我正在尝试编写一个数独求解器,它将仅返回第一个可能的解决方案。 我设法用 void 方法打印所有可能的解决方案,但我不能在第一个发现时停止。

我知道首选方法是切换到布尔方法并在树上返回 true - 但我找不到正确的写法。

我尝试的任何方法总是给出编译错误(方法必须返回布尔值)。

public boolean recursiveSolve(int line, int column) {
    if(line == N) // N is the board size (9)
        return true;
    // if Cell is not empty - continue
    if(board1.getCell(line, column) != 0) { 
        return nextCell(line, column);
    }
    // if Cell empty - solve
    else { 
        for(int i = 1; i <= N; i++) {
            board1.setCell(line, column, i); // set value to cell
            if(board1.boardIsOk())           // check if the board is legal
                return nextCell(line, column); // continue
        }
        board1.setCell(line, column, 0);     // backtrack
    }
}

private boolean nextCell(int line, int column) {
    if(column < 8)
        return recursiveSolve(line, column+1); // progress up the row
    else
        return recursiveSolve(line+1, 0);      // progress down the lines
}

任何帮助将不胜感激。

i'm trying to write a Sudoku solver which will return only the first possible solution.
i managed to print all possible solutions with void methods but i can't stop on the first find.

i know the preferred way is to switch to boolean methods and return true up the tree -
but i can't find the right way to write it.

any way i tried always give compilation errors (method must return boolean).

public boolean recursiveSolve(int line, int column) {
    if(line == N) // N is the board size (9)
        return true;
    // if Cell is not empty - continue
    if(board1.getCell(line, column) != 0) { 
        return nextCell(line, column);
    }
    // if Cell empty - solve
    else { 
        for(int i = 1; i <= N; i++) {
            board1.setCell(line, column, i); // set value to cell
            if(board1.boardIsOk())           // check if the board is legal
                return nextCell(line, column); // continue
        }
        board1.setCell(line, column, 0);     // backtrack
    }
}

private boolean nextCell(int line, int column) {
    if(column < 8)
        return recursiveSolve(line, column+1); // progress up the row
    else
        return recursiveSolve(line+1, 0);      // progress down the lines
}

Any help will be most appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

横笛休吹塞上声 2025-01-05 05:04:28

这是大多数递归回溯问题的一些伪代码。

如果您已经找到解决方案,请报告成功。

for(当前位置的所有可能选择){

做出选择并沿着这条路迈出一步。

使用递归从新的位置解决问题。

如果递归调用成功,向上级报告成功
级别。

退出当前选择,恢复开始时的状态
循环的。

}

报告失败。

这是一些基于斯坦福大学讲座的实际代码。我用java重新编写了它并添加了注释。

Boolean SolveSudoku(int[][] grid)
{
    int row, col;

    if(!FindUnassignedLocation(grid, row, col))
        //all locations successfully assigned
        return true;

    for(int num = 1; num <= 9; num++)
    {
        //if number is allowed to be placed in the square
        if(NoConflicts(grid, row, col, num))
        {
            //place the number in the square
            grid[row][col] = num;

            //recur, if successful then stop
            if(SolveSudoku(grid))
                return true;

            //undo and try again
            grid[row][col] = UNASSIGNED;
        }
     }
     //this triggers backtracking from early decisions
     return false;
}

您只需要实现一些非常简单的方法。

Here is some pseudocode for most recursive backtracking problems.

If you are already at a solution, report success.

for (every possible choice in the current position ) {

Make that choice and take one step along the path.

Use recursion to solve the problem from the new position.

If the recursive call succeeds, report the success to the next higher
level.

Back out of the current choice to restore the state at the beginning
of the loop.

}

Report failure.

Here is some actual code based on a lecture from Stanford. I re-wrote it in java and included comments.

Boolean SolveSudoku(int[][] grid)
{
    int row, col;

    if(!FindUnassignedLocation(grid, row, col))
        //all locations successfully assigned
        return true;

    for(int num = 1; num <= 9; num++)
    {
        //if number is allowed to be placed in the square
        if(NoConflicts(grid, row, col, num))
        {
            //place the number in the square
            grid[row][col] = num;

            //recur, if successful then stop
            if(SolveSudoku(grid))
                return true;

            //undo and try again
            grid[row][col] = UNASSIGNED;
        }
     }
     //this triggers backtracking from early decisions
     return false;
}

You just need to implement a few methods, which are pretty trivial.

转身以后 2025-01-05 05:04:28

变成

        if(board1.boardIsOk())           // check if the board is legal
            return nextCell(line, column); // continue

        if(board1.boardIsOk()) {          // check if the board is legal
            boolean solved = nextCell(line, column); // continue
            if (solved) {
                return true;
            ]
        }
    ...
    return false;

Change

        if(board1.boardIsOk())           // check if the board is legal
            return nextCell(line, column); // continue

into

        if(board1.boardIsOk()) {          // check if the board is legal
            boolean solved = nextCell(line, column); // continue
            if (solved) {
                return true;
            ]
        }
    ...
    return false;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文