Java 带回溯的数独递归
我试图用递归回溯算法解决任何给定的数独难题。我的数独解算器有两个问题。首先,它解决了这个谜题,但是它会在这个过程中递归备份并取消解谜(大约4718个解会递归并继续进行10000个左右的备份)。第二个问题源于我试图解决这个问题。我使用全局矩阵解决方案在找到解决方案后保存该解决方案,验证我是否已使用如下所示的IsResolved方法找到该解决方案:Java 带回溯的数独递归,java,recursion,sudoku,backtracking,Java,Recursion,Sudoku,Backtracking,我试图用递归回溯算法解决任何给定的数独难题。我的数独解算器有两个问题。首先,它解决了这个谜题,但是它会在这个过程中递归备份并取消解谜(大约4718个解会递归并继续进行10000个左右的备份)。第二个问题源于我试图解决这个问题。我使用全局矩阵解决方案在找到解决方案后保存该解决方案,验证我是否已使用如下所示的IsResolved方法找到该解决方案: public static boolean isSolved(int[][]puzzle){ for(int i = 0;
public static boolean isSolved(int[][]puzzle){
for(int i = 0; i<9; i++){ //y rotation
for(int j = 0; j<8; j++){
if(puzzle[i][j]==0){
return false;
}
}
}
return true;
}
publicstaticbooleanissolved(int[]]puzzle){
对于(int i=0;i如果我正确理解了您的代码,那么问题似乎在于递归没有得到很好的实现,从这个意义上讲,即使在找到正确答案后,您的程序仍将继续循环最后一个for循环
例如,在第一个空格中,正确的数字是4。但是程序正在考虑的可能的数字列表(此时)是{2,4,6,7}。在这种情况下,它似乎会在4处找到正确的答案,并生成正确的输出。但它仍会检查6和7。由于它(当然)找不到任何答案,它会将输入留空,并返回原始板
现在,虽然我认为您在某种程度上正确地设置了一个全局变量来存储实际答案,但问题是您没有生成数组的副本,而只是复制指向它的指针(引用)
您可以简单地创建一个复制方法来实际复制整个数组,但请记住,即使生成了正确的答案,您的算法仍将不必要地循环并浪费时间
作为参考,这里是我编写的solve方法,其中我的isValid()方法与您的isTrue()等效:
公共静态最终整数大小=9;
公共静态布尔解算(int[]s){
对于(int i=0;i 对于(int num=1;num)“正在重置”是什么意思?它解决了这个问题,然后继续将它还原到原来的空谜题,只剩下原来的点。非常感谢,这解决了这么多问题。看起来使用布尔递归方法解决这个问题是更好的答案。非常感谢您的洞察力!好书:,@Allbeert:这是一个非常有趣的解决方案与解决回溯问题的一般方法略有不同的解决方案:您可以在这里(第3页及以后)找到一般方法。有趣的是,在您的解决方案中,最终的返回true
完全颠倒了w.r.t.一般解决方案
public static int[][] solve(int[][]puzzle, int x, int y){
System.out.println("RecrDepth: " + recDepth);
recDepth++;
//using backtracking for brute force power of the gods(norse cause they obviously most b.a.
ArrayList<Integer> list = new ArrayList<Integer>();
//next for both x and y
int nextx = getNextx(x);
int nexty = getNexty(x, y);
while(puzzle[y][x] != 0){ //progress until blank space
x = nextx;
y = nexty;
if(isSolved(puzzle)){
System.out.println("resetting solution improperly");
solution = puzzle;
return puzzle;
}
nextx = getNextx(x);
nexty = getNexty(x, y);
}
for(int i = 1; i<10; i++){
if(isTrue(puzzle, y, x, i)) //isTrue checks column, row and box so we dont go down unnecessary paths
list.add(i);
}
for(int i=0; i<list.size(); i++){ //iterating through options in open squre recursing for each one
puzzle[y][x]= list.get(i);
if(isSolved(puzzle)){
System.out.println("Resetting Solution"); //appears to reset solution here but only once that I see in print out
solution = puzzle;
return puzzle;
}
System.out.print("=");
puzzle = solve(puzzle, nextx, nexty);
puzzle[y][x] = 0;//clear spot upon backtracking THIS WAS WHAT I WAS MISSIN
}
return puzzle;
}
public static final int SIZE = 9;
public static boolean solve(int[][] s) {
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
if (s[i][j] != 0) {
continue;
}
for (int num = 1; num <= SIZE; num++) {
if (isValid(num, i, j, s)) {
s[i][j] = num;
if (solve(s)) {
return true;
} else {
s[i][j] = 0;
}
}
}
return false;
}
}
return true;
}