我的数独回溯算法只有部分时间能用,谁能帮我改进一下?

问题描述 投票:0回答:1

我有一个递归算法,它应该接收一个部分或全部为空的数独棋盘(用int[][]表示,其中0代表空白),并填充它。它对空棋盘和我输入的大多数其他棋盘都有效,但偶尔我得到一个堆栈溢出错误,指向第54行和第40行(在语句grid = copyGrid(emptyFill(grid, current + 1, cant)); )。谁能帮我改进一下?

  //Creating and filling a board Recursive Methods
//Current represents the index for every cell on the board from 0 to 80 inclusive
//cant holds an array of values that the function may not place for each index 
public static int[][] emptyFill(int[][] grid, int current, int[][] cant){
    if(isFull(grid)){
        return grid; 
    } 
    else if(getCellAt(grid, current) == 0){
        for(int i = 1; i <= 9; i ++){
            if(works(i, current / 9, current % 9, grid) && notInCant(cant, current, i)){
                grid[current / 9][current % 9] = i;
                //Line 40 below this comment
                grid = copyGrid(emptyFill(grid, current + 1, cant));
                return grid; 
            }
        }
        /*Backtracks backwards if no number was found by keeping track of what numbers we have tried. Should clear 
        up the cant list if we backtrack further than it */
        for(int i = current; i < cant.length; i ++){
            clearRow(cant, i);
        }
        addToRow(cant, current - 1,  getCellAt(grid, current - 1)); 
        setCellTo(grid, current, 0); 
        setCellTo(grid, current - 1, 0); 
        //Line 54 below this comment
        grid = copyGrid(emptyFill(grid, current -1, cant));
        return grid; 
    }
    else{
        grid  = copyGrid(emptyFill(grid, current + 1, cant));
        return grid; 
    }

}
java algorithm recursion stack-overflow backtracking
1个回答
0
投票

问题是,当程序无法填入一个单元格时,它会 "回溯",通过清除当前和前一个单元格,更新无法放置的数字列表,然后再次调用程序。这导致该函数被调用太多次。新函数则是简单地清除单元格,当找不到合适的号码时,就退出函数。这样就可以让函数回溯,不用再调用自己,实际上又回到了之前的调用。这就是更新后的函数。

public boolean emptyFill(int[][] grid, int current){
    if(isFull(grid)){
        return true; 
    } 
    else if(getCellAt(grid, current) == 0){
        for(int i = 1; i <= 9; i ++){
            if(works(i, current / 9, current % 9, grid) && notInCant( current, i)){
                grid[current / 9][current % 9] = i;
                if( emptyFill(grid, current + 1)) return true; 
                grid[current / 9][current % 9] = 0;
            }
        }
        return false; 
    }
    else{
       return emptyFill(grid, current + 1);
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.