2016-10-01 68 views
0

我正在制作一个数独求解器,它在正方形和回溯中尝试每个可能的值,如果它不导致解决方案。我相信我有一个接近工作的算法,但它仅在16格拼图的第0行,第2行和第3行工作。数独算法不能正确回溯

public boolean fillBoard(int[][] board, int row, int col){ 
    int index = 1;    //Next value to try when an empty is found 
    boolean solved = false; 

    for(int i = row; i < width; i++){  //For each row 
     for(int j = col; j < height; j++){ //For each column 
      if(board[i][j]==0){    //0 represents empty 
       while(!solved){ 
        board[i][j] = index; 
        if(checker.checkRow(board[i]) 
          && checker.checkColumn(columnToArray(board, j)) 
          //&& checker.checkBox(<input>) 
          ){ 
          solved = fillBoard(board, i, 0); 
        }else{ 
         if(index < width){ 
          index++; 
         }else{ 
          return false; 
         } 
        } 
       } 
      } 
     } 
    } 
    puzzle = copyPuzzle(board); 
    return true; 
} 

现在它不检查第三个数独规则,它只检查列和行。但是,它仍然会返回一个符合行和列规则的难题,对吗?一旦checkBox方法被写入,它应该能够解决这个难题。我在这里搞到了什么?

EDIT与几个例子:

对于

 {1, 2, 0, 0}, 
     {0, 4, 0, 0}, 
     {0, 0, 1, 0}, 
     {0, 0, 3, 2} 

输入程序返回

1 2 4 3 4 4 4 4 2 3 1 4 4 1 3 2

对于

 {1, 0}, 
     {2, 0} 
输入0

它正确解决了它。

对于

 { 1, 0, 3, 4, 0, 0 }, 
     { 4, 0, 6, 0, 0, 3 }, 
     { 2, 0, 1, 0, 6, 0 }, 
     { 5, 0, 4, 2, 0, 0 }, 
     { 3, 0, 2, 0, 4, 0 }, 
     { 6, 0, 5, 0, 0, 2 } 

它返回难题未解的输入

编辑:checkRow对于那些谁问

public boolean checkRow(int[]row){ 
    HashSet<Integer> set = new HashSet<Integer>(); 
    for(int i = 0; i < row.length;i++){ 
     if(!set.add(row[i]) && row[i]>0){//Duplicate? 
      return false; 
        } 
       } 
    return true; 
} 
+0

请提供具体的例子,它不起作用。 –

+0

@ScottHunter我加了几个例子 – realmature

+0

'checkRow'和'checkColumn'只是验证当前行/列不包含'0'?递归的退化情况似乎很难定义,这将解释算法在最后一个实例中返回未解决的难题。我认为你的'return true'需要'返回解决',并且'solve'的值需要根据你的基本情况进行更新。 – nbrooks

回答

1

的问题是,它没有重置空间当值不正确时为0,所以如果它达到最大索引并且不正确,它就会离开它。下面的代码工作。只是等待我的小组中的另一个人提供盒子检查方法,但我可能最终不得不自己这样做。

public boolean fillBoard(int[][] board, int row, int col){ 
    int index = 1;    //Next value to try when an empty is found 
    boolean solved = false; 

    for(int i = row; i < width; i++){  //For each row 
     for(int j = col; j < height; j++){ //For each column 
      if(board[i][j]==0){    //0 represents empty 
       while(!solved){    //While the puzzle is unsolved 
        board[i][j] = index; //Try to fill with index 
        if(checker.checkRow(board[i]) 
          && checker.checkColumn(columnToArray(board, j)) 
          //&& checker.checkBox(<input>) 
          ){ 
          solved = fillBoard(board, i, 0); //Next space 
        } 
        if(!solved) board[i][j] = 0; 
        if(index < width){ 
         index++; 
        }else{ 
         return false; 
        }       
       } 
      } 
     } 
    } 
    puzzle = copyPuzzle(board); 
    return true; 
}