Java 递归回溯问题

Java 递归回溯问题,java,algorithm,sudoku,Java,Algorithm,Sudoku,我试图用Java实现一个回溯算法,来解决一个数独问题 我95%确定问题出在解决方法上,但我在案例中包括了两种辅助方法 我所做的一些奇怪的事情只是出于需求/便利,比如拼图的硬编码初始值。我确信问题就在我的解决方法的底部,但我无法解决它 我目前的问题是:在处理第一行并找到可能有效的值排列后,我的程序就放弃了。如果我取消对打印“ROW IS DONE”的行的注释,它将在一行之后打印该行,并且不会给出更多的输出。为什么在第一排之后就放弃了?关于我的实施,还有什么我应该担心的吗 编辑:我做了很多改变。它越

我试图用Java实现一个回溯算法,来解决一个数独问题

我95%确定问题出在解决方法上,但我在案例中包括了两种辅助方法

我所做的一些奇怪的事情只是出于需求/便利,比如拼图的硬编码初始值。我确信问题就在我的解决方法的底部,但我无法解决它

我目前的问题是:在处理第一行并找到可能有效的值排列后,我的程序就放弃了。如果我取消对打印“ROW IS DONE”的行的注释,它将在一行之后打印该行,并且不会给出更多的输出。为什么在第一排之后就放弃了?关于我的实施,还有什么我应该担心的吗

编辑:我做了很多改变。它越来越近了。如果我在排气为真时打印,我会得到一个谜题,除最后一行外,每一行都已解决。它看起来像是在解决/几乎解决它之后,它正在撤销一切。我有一种感觉,它可能已经达到了一个谜题完全解决的地步,但我并没有在正确的时间返回真的。。。我现在做错了什么

import java.util.ArrayList;

class Model
{
    ArrayList<View> views = new ArrayList<View>();
    int[][] grid = 
            {
              {5,3,0,0,7,0,0,0,0},
              {6,0,0,1,9,5,0,0,0},
              {0,9,8,0,0,0,0,6,0},
              {8,0,0,0,6,0,0,0,3},
              {4,0,0,8,0,3,0,0,1},
              {7,0,0,0,2,0,0,0,6},
              {0,6,0,0,0,0,2,8,0},
              {0,0,0,4,1,9,0,0,5},
              {0,0,0,0,8,0,0,7,9}
            };

    /**
     * Method solve
     * 
     * Uses a backtracking algorithm to solve the puzzle.
     */
    public boolean solve(int row, int col) //mutator
    {   
        if(exhaust(row,col)) {printGrid(); return true;}
        int rownext = row;
        int colnext = col+1;
        if(colnext>8)
        {
            colnext = 0;
            rownext++;
        }           
        if(grid[row][col] != 0) solve(rownext,colnext);
        else //is == 0
        {
            for(int num = 1; num <= 9; num++)
            {   
                if(!conflict(row,col,num)) //try a non-conflicting number   
                {
                    grid[row][col] = num;
                    if(solve(rownext,colnext)) return true;                     
                    grid[row][col] = 0;
                }
            }
        }
        return false;       

    }
    /**
     * Method exhaust
     * 
     * Iteratively searches the rest of the puzzle for empty space
     * using the parameters as the starting point.
     *
     * @return true if no 0's are found
     * @return false if a 0 is found
     */
    public boolean exhaust(int row, int col)
    {
        for(int i = row; i <= 8; i++)
        {
            for(int j = col; j <= 8; j++)
            {
                if(grid[i][j] == 0) return false;
            }
        }
        System.out.printf("Exhausted.\n");
        return true;
    }

    /**
     * Method conflict
     * 
     * Checks if the choice in question is valid by looking to see
     * if the choice has already been made in the same row or col,
     * or block. 
     *
     * @return true if there IS a conflict
     * @return false if there is NOT a conflict
     */
    public boolean conflict(int row, int col, int num)
    {
        for(int j = 0; j <= 8; j++)
        {
            if(grid[row][j] == num) {
                return true;
            }
        }   
        for(int i = 0; i <= 8; i++)
        {
            if(grid[i][col] == num) {
                return true;
            }
        }           

        int rowstart = 0;
        if(row>=3) rowstart = 3;
        if(row>=6) rowstart = 6;

        int colstart = 0;
        if(col>=3) colstart = 3;
        if(col>=6) colstart = 6;                    

        for(int r = rowstart; r <= (rowstart + 2); r++)
        {
            for(int c = colstart; c <= (colstart + 2); c++)
            {
                if(grid[r][c] == num) {
                    return true;
                }   
            }   
        }       
        return false;
    }
}
import java.util.ArrayList;
类模型
{
ArrayList视图=新建ArrayList();
int[][]网格=
{
{5,3,0,0,7,0,0,0,0},
{6,0,0,1,9,5,0,0,0},
{0,9,8,0,0,0,0,6,0},
{8,0,0,0,6,0,0,0,3},
{4,0,0,8,0,3,0,0,1},
{7,0,0,0,2,0,0,0,6},
{0,6,0,0,0,0,2,8,0},
{0,0,0,4,1,9,0,0,5},
{0,0,0,0,8,0,0,7,9}
};
/**
*方法求解
* 
*使用回溯算法来解决难题。
*/
公共布尔解算(int行,int列)//mutator
{   
if(排气(行,列)){printGrid();返回true;}
int rownext=行;
int colnext=col+1;
如果(colnext>8)
{
colnext=0;
rownext++;
}           
如果(网格[行][列]!=0)求解(行下一步,列下一步);
else//is==0
{

对于(int num=1;num想象你正在一行一行地顺利前进,并且没有后退。你的下一个位置是
solve(1,1)
。在跟踪代码时,请注意rownext。您应该很快看到问题所在。如果您没有回溯,rownext的值应至少保持为1。

如果您使用的是Eclipse或其他高级IDE,请开始使用调试器。您可以一步一步地查看程序将引导到哪里。@PM77-1我尝试设置了e我想我上次使用eclipse是在使用windows的时候,这很好,但要在*nix上运行它似乎太麻烦了……你指出了他注意到的问题,但是
detain()也有问题
。我也不确定回溯是否有效…编辑我认为回溯确实有效,但我不确定为什么你不返回一个
布尔值来短路某些逻辑?你的意思是,将solve重写为boolean方法?我只把它写成void,因为这是我的教授提供的psuedo代码所建议的。我想这样做会更容易,但可能不会。我知道一个更好的问题可能会对我有所帮助。我一直在思考回溯需要如何工作……应该只检查是否有更多的空间可以尝试,还是应该验证到目前为止所做的每一个决定?我在思考最后一步,我有一个填好的谜题,我不确定如何/在何处检查所有数字,以查看是否一切都正常,或者这是否应该只在谜题解决时发生…编辑:无需担心,我可能应该写一个更完整的“冲突”方法,对吗?您对电路板耗尽时间的测试可以在
rownext++
之后立即进行,只需检查rownext==9。这将节省一些不必要的处理。我不是想分散您的注意力。您有一行代码,
if(grid[row][col col]!=0)solve(rownext,colnext);
.if
solve(rownext,colnext)
返回true,即使找到以前的解决方案,您的代码仍将继续尝试求解。