可能重复:
Sudoku solver in java, using backtracking and recursion
我正在创建一个程序,它将使用递归和暴力解决数独。我的关键问题是,我不明白我是如何能够令人难以置信地让它重新陷入困境。
该程序的一般算法如下:
查找数独中的零个数。
在第一个0的位置(getNextEmpty方法执行此操作),插入一个数字(insertnumber检查以确保值符合数独规则,如果存在则返回true)。
然后我进行递归调用,当没有更多的零时结束(n是零的数量)。
如果程序达到了卡住的程度,我必须回溯才能更改。但这怎么可能呢?
Cell类实际上以[row,column]格式的数组的形式保存要调整的单元格的位置。它具有返回与该单元格关联的行,列或较小网格的方法。
我不是要求手持或所有代码,只要在正确的方向上轻推就足够了,因为我对理解递归有合法的兴趣。
public static int[][] getSolution(int[][] grid) {
for (int i = 0; i < 9; i++) {
System.arraycopy(grid[i], 0, SolveSudoku.grid[i], 0, 9);
}// end for
int n = getZeroes();
return getSolution(n);
}//end getSolution
private static int[][] getSolution(int n) {
if (n == 0) {
return grid;
}//end if
Cell cell = getNextEmpty();
boolean fits = false;
for (int i = 0; i <= 9; i++) {
fits = insertNumber(cell, i);
if (fits) {
break;
}else {
//I do not understand what I should do here
}
}//end for
return getSolution(n - 1);
}//end getSolution
答案 0 :(得分:2)
向正确的方向轻推。您的方法需要稍微调整,因为您没有跟踪解决网格所需的所有信息。
private static int[][] getSolution(int n) {
if (n == 0) {
return grid;
}//end if
Cell cell = getNextEmpty();
boolean fits = false;
for (int i = 0; i <= 9; i++) {
fits = insertNumber(cell, i);
if (fits) {
break; // means i fits in Cell
} else {
// i doesn't fit... try the next i
// don't need to do anything
}
}//end for
if (!fits) {
// There are no numbers that fit in this Cell
// What should happen?
// Did I make a bad guess?
// How do I BACKTRACK and correct a previous guess?
}
return getSolution(n - 1);
}//end getSolution
答案 1 :(得分:1)
通常在递归暴力中,您使用类似于以下代码的语法。之所以这样做是因为你可以在做完任何动作后计算出来,那就是新的“起始位置”。 所以它类似于:
private void Guess(int[][] grid)
{
if(/**grid is a solution **/)
//signal success
else
{
if(/*seed out any bad, unacceptable answers you may have missed*/)
return;//this includes cases when there are no more zeros
//for every possible move,
//make a modified grid, with one move done, and call
Guess(ModifiedGrid);//for every possible move, generally you can modify
//grid itself, because its passed by value
}
}