回溯数独解算器的递归问题[Java]
问题:用Java编写回溯数独解算器,该解算器接收表示谜题的文件,将其转换为矩阵,然后使用递归回溯解决问题
问题:在我的解决方法中,它将尝试解决第一个空框,但不会越过该框
错误日志:
Exception in thread "main" java.lang.StackOverflowError at java.util.AbstractCollection.(AbstractCollection.java:49)
at java.util.AbstractList.(AbstractList.java:59)
at java.util.ArrayList.(ArrayList.java:108)
at java.util.ArrayList.(ArrayList.java:119)
at ssolver.solve(ssolver.java:67)
at ssolver.solve(ssolver.java:83)
at ssolver.solve(ssolver.java:83)
...
方法:
public static int[][] solve(int[][]puzzle, int x, int y){
//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, nexty=y;
if(x == 8){
nextx=0;
nexty=y+1;
}
else{
nextx=x++;
}
if(isSolved(puzzle))
return puzzle;
if(!(puzzle[y][x]==0))
solve(puzzle, nextx, nexty);
else{
for(int i =1; i<10; i++){
if(isTrue(puzzle, y, x, i))
list.add(i);
}
for(int i : list){
puzzle[y][x] = list.get(i);
printPuzzle(puzzle);//prints here for testing
if(isSolved(puzzle)||(x==8&&y==8));
else{
solve(puzzle, nextx, nexty);
}
}
}
return puzzle;
}
有人能告诉我哪里出了问题吗。如果我做错了什么事,在第一次发帖时提前道歉。 干杯
# 1 楼答案
所采用的算法类似于用于解决八皇后难题的标准回溯,如图所示:http://en.wikipedia.org/wiki/Eight_queens_puzzle
下面是Bob Carpenter(http://www.colloquial.com/carp)提供的一个类
这个代码示例帮助我解决了一个数独游戏的回溯问题。 经过一点调查,我能够重新编码,以适应我的程序
如果您在理解此代码的逻辑时遇到问题,请回复消息
下面的代码是直接从他的源代码复制粘贴的
# 2 楼答案
StackOverflowError
表示已超过递归深度限制显然,对这个问题使用递归不是一个好主意
在没有递归的情况下实现这样的代码更难,但您没有其他选择
你可以从这篇文章Replace Recursion with Iteration中得到一些启发
# 3 楼答案
请注意,sudoko拼图需要大约9*9=81的深度才能工作,因此这可能是一个过度的操作
另一个原因是你检查了所有可能的数字,所以它是9^9=387420489个可能的组合
您至少应该添加一个函数isValid来解决这个难题,以避免运行无效的“分支”并进一步使用它们
为了有效地解决这个问题,你应该使它易于使用,并且为每个单元格输入你可以使用的可能的数字
here's a link关于求解sudoko的工作原理(请看数字4)。在为每个单元格输入所有数字后,您所要做的就是一步一步地按照逻辑消除数字
只有在使用了所有逻辑规则之后,才可以使用递归方法(或itereation)。这将使您的算法比任何其他回溯算法更高效、更快