带回溯的数独算法-java
所以我有一个大学作业要解决数独。。。我读了关于算法X和舞蹈算法的书,但他们没有帮我 我需要回溯。我用维基百科给出的数字对二维数组中的一些索引进行了硬编码(因此我确信它是可解的) 我得到的代码如下:带回溯的数独算法-java,java,algorithm,sudoku,backtracking,Java,Algorithm,Sudoku,Backtracking,所以我有一个大学作业要解决数独。。。我读了关于算法X和舞蹈算法的书,但他们没有帮我 我需要回溯。我用维基百科给出的数字对二维数组中的一些索引进行了硬编码(因此我确信它是可解的) 我得到的代码如下: public void solveSudoku(int row, int col) { // clears the temporary storage array that is use to check if there are // dublicates on the
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;
}
这意味着我必须在某个时刻停止递归,但我不知道该怎么做!
如果在
solve()
函数中发现任何其他错误,请告诉我。因为我不确定我是否完全理解“回溯”这件事…你可以停止递归,例如,如果你跟踪当前的递归深度
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()函数中发现任何其他错误,请告诉我
代码太多:)这大概是我过去做这件事的方式
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.
我用了一种更简单的方法:
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;
}
public void solve(int行,int列)
{
如果(第8行)
{
印制板();
System.out.println();
返回;
}
如果(板[行][列]!=0)
{
if(col<8)
求解(行,列+1);
其他的
求解(行+1,0);
}
其他的
{
对于(int i=0;i<10;i++)
if(检查行(行,i)和检查列(列,i))
//&&方格(行、列、i))
{
板[行][col]=i;
if(col<8)
求解(行,列+1);
其他的
求解(行+1,0);
}
线路板[行][列]=0;
}
}
专用布尔检查行(int行,int numberToCheck)
{
对于(int i=0;i<9;i++)
if(板[行][i]==数字检查)
返回false;
返回true;
}
专用布尔检查列(整数列,整数编号检查)
{
对于(int i=0;i<9;i++)
if(板[i][col]==数字检查)
返回false;
返回true;
}
我不知道你为什么说跳舞链接和算法X没有用。你的意思是说你无法将数独映射到算法X设计用来解决的精确覆盖问题的实例吗?
或者对于你需要的东西来说,这是一个太复杂的方法 如果是前者,您可能需要查看:。这很清楚,也解释了背后的原因 注意,算法X是一种回溯算法,所以,如果这是您唯一的要求,您肯定可以使用这种方法
希望这能有所帮助。有一个很好的例子你应该看看你的dublicates代码。我不明白这怎么能检查一个数字是否被允许。你总是重置它(每次数独调用),所以它会忘记一切。我还怀疑9个元素的数组如何检查所有的东西。好吧,我没有说跳舞链接和算法X是没有用的。我说我不能真正理解它们,所以我不能使用它们。但是我会读你给我的链接上写的内容。谢谢;)
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;
}