Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带回溯的数独算法-java_Java_Algorithm_Sudoku_Backtracking - Fatal编程技术网

带回溯的数独算法-java

带回溯的数独算法-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

所以我有一个大学作业要解决数独。。。我读了关于算法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;
   }
这意味着我必须在某个时刻停止递归,但我不知道该怎么做!
如果在
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;
   }