所以我有这个大学任务解决数独...我读了算法X和跳舞算法,但他们没有帮助我。
我需要回溯。我用维基百科给出的地方用二维数字中的一些索引进行了硬编码(所以我确信它是可以解决的)。
我得到的代码如下:
public void solveSudoku(int row, int col)
{
// clears the temporary storage array that is use to check if there are
// dublicates on the row/col
for (int k = 0; k < 9; k++)
{
dublicates[k] = 0;
}
// checks if the index is free and changes the input number by looping
// until suitable
if (available(row, col))
{
for (int i = 1; i < 10; i++)
{
if (checkIfDublicates(i) == true)
{
board[row][col] = i;
if (row == 8)
solveSudoku(0, col + 1);
else if (col == 8)
solveSudoku(row + 1, 0);
else
solveSudoku(row, col + 1);
board[row][col] = 0;
}
}
}
// goes to the next row/col
else
{
if (row == 8)
solveSudoku(0, col + 1);
else if (col == 8)
solveSudoku(row + 1, 0);
else
solveSudoku(row, col + 1);
}
}
/**
* Checks if the spot on the certain row-col index is free of element
*
* @param row
* @param col
* @return
*/
private boolean available(int row, int col)
{
if (board[row][col] != 0)
return false;
else
return true;
}
/**
* Checks if the number given is not already used in this row/col
*
* @param numberToCheck
* @return
*/
private boolean checkIfDublicates(int numberToCheck)
{
boolean temp = true;
for (int i = 0; i < dublicates.length; i++)
{
if (numberToCheck == dublicates[i])
{
temp = false;
return false;
}
else if (dublicates[i] == 0)
{
dublicates[i] = numberToCheck;
temp = true;
return true;
}
}
return temp;
}
我正在使用
上的StackOverflow// goes to the next row/col
else
{
if (row == 8)
solveSudoku(0, col + 1);
else if (col == 8)
solveSudoku(row + 1, 0);
else
solveSudoku(row, col + 1);
}
这意味着我必须在某个时候停止递归,但我无法弄清楚如何!
如果您在solve()
函数中发现任何其他错误 - 请告诉我。因为我不确定我完全理解“回溯”的事情......
答案 0 :(得分:3)
例如,如果跟踪当前的递归深度,可以停止递归
public void solveSudoku(int row, int col, int recursionDepth) {
// get out of here if too much
if (recursionDepth > 15) return;
// regular code...
// at some point call self with increased depth
solveSudoku(0, col + 1, recursionDepth + 1);
}
如果你在solve()函数中发现任何其他错误 - 请告诉我。
代码过多:)
答案 1 :(得分:3)
这大致是我过去做过的方式。
Whenever all the definite moves have been taken and there is a choice of equally good next moves:
copy your grid data structure and push it onto a stack.
take the first candidate move and continue solving recursively
Whereever you get stuck:
pop the saved grid off the stack
take the next candidate move.
答案 2 :(得分:1)
我以更简单的方式制作:
public void solve(int row, int col)
{
if (row > 8)
{
printBoard();
System.out.println();
return;
}
if (board[row][col] != 0)
{
if (col < 8)
solve(row, col + 1);
else
solve(row + 1, 0);
}
else
{
for (int i = 0; i < 10; i++)
if (checkRow(row, i) && checkCol(col, i))
//&& checkSquare(row, col, i))
{
board[row][col] = i;
if (col < 8)
solve(row, col + 1);
else
solve(row + 1, 0);
}
board[row][col] = 0;
}
}
private boolean checkRow(int row, int numberToCheck)
{
for (int i = 0; i < 9; i++)
if (board[row][i] == numberToCheck)
return false;
return true;
}
private boolean checkCol(int col, int numberToCheck)
{
for (int i = 0; i < 9; i++)
if (board[i][col] == numberToCheck)
return false;
return true;
}
答案 3 :(得分:1)
我不确定你为什么说跳舞链接和算法X没用
你的意思是你无法将Sudoku映射到算法X旨在解决的Exact Cover问题的实例吗?
或者说这对你需要的东西来说太复杂了?
如果是前者,您可能需要查看:A Sudoku Solver in Java implementing Knuth’s Dancing Links Algorithm。这很清楚,也解释了背后的原因。
N.B。算法X是一种回溯算法,因此,如果这是你唯一的要求,你绝对可以使用这种方法。
希望这可以提供帮助。