逻辑解算算法(适用于Java中的Sudoku)

前端之家收集整理的这篇文章主要介绍了逻辑解算算法(适用于Java中的Sudoku)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有我的逻辑解算算法的问题.它很好地解决了大量提示的难题,它只是具有少于45个线索的难题的问题.

这是求解的算法. Immutable是一个布尔值,用于确定该值是否可以更改. cell [row] [col] .possibleValues是一个名为SudokuCell的类中的LinkedList,用于存储该网格元素可能的值. grid.sGrid是谜题的主要int [] []数组. removeFromCells()是从网格的行,列和象限中删除值的方法.该代码进一步提供.

第二个for循环仅用于检查单个解决方案.我决定避免递归,因为我真的不能让我的头脑.这种方法现在似乎工作得很好.

  1. public boolean solve(){
  2.  
  3. for(int i = 0; i < 81; i++){
  4. for(int row = 0; row < 9; row++){
  5. for(int col = 0; col < 9; col++){
  6. if(!immutable[row][col]){
  7. if(cell[row][col].getSize() == 1){
  8. int value = cell[row][col].possibleValues.get(0);
  9. grid.sGrid[row][col] = value;
  10. immutable[row][col] = true;
  11. removeFromCells(row,col,value);
  12. }
  13. }
  14. }
  15. }
  16. }
  17.  
  18.  
  19. int i = 0;
  20. for(int row = 0; row < 9; row++){
  21. for(int col = 0; col < 9; col++){
  22. if(grid.sGrid[row][col] == 0){
  23. i++;
  24. }
  25. }
  26. }
  27.  
  28. if(i != 0){
  29. return false;
  30. } else{
  31. return true;
  32. }
  33. }

这是removeFromCells()的代码

我认为大部分的代码是不言自明的.第一个for循环从(x,y)的行和列中删除值,第二个循环从象限中删除该值.

  1. public void removeFromCells(int x,int y,int value){
  2.  
  3. /*
  4. * First thing to do,find the quadrant where cell[x][y] belong.
  5. */
  6.  
  7. int topLeftCornerRow = 3 * (x / 3) ;
  8. int topLeftCornerCol = 3 * (y / 3) ;
  9.  
  10. /*
  11. * Remove the values from each row and column including the one
  12. * where the original value to be removed is.
  13. */
  14. for(int i = 0; i < 9; i++){
  15. cell[i][y].removeValue(value);
  16. cell[x][i].removeValue(value);
  17. }
  18.  
  19.  
  20. for(int row = 0; row < 3; row++){
  21. for(int col = 0; col < 3; col++){
  22. cell[topLeftCornerRow + row][topLeftCornerCol + col].removeValue(value);
  23. }
  24. }
  25. }

另一个问题点可能在于构建可能的值.这是我的方法

第一个for循环创建新的SudokuCells以避免可怕的空指针异常.

sGrid中的任何空值都表示为0,因此for循环将跳过这些值.

SudokuBoard的构造函数调用这个方法,所以我知道它正在被调用.

  1. public void constructBoard(){
  2.  
  3. for(int row = 0; row < 9; row++){
  4. for(int col = 0; col < 9; col++){
  5. cell[row][col] = new SudokuCell();
  6. }
  7. }
  8.  
  9. immutable = new boolean[9][9];
  10.  
  11. for(int row = 0; row < 9; row++){
  12. for(int col = 0; col < 9; col++){
  13. immutable[row][col] = false;
  14. if(grid.sGrid[row][col] != 0){
  15. removeFromCells(row,grid.sGrid[row][col]);
  16. immutable[row][col] = true;
  17. }
  18. }
  19. }
  20. }

我会发布整个文件,但在那里有很多不必要的方法.我发布了我认为是导致我的问题.

解决方法

你似乎只建立了一个解决现在的简单约束.你需要一个完整的后跟,以便用较少的提示解决谜题.在某些情况下,您无法真正解决没有回溯.

或者,您应该尝试实现Knuth的算法(Dancing Links)来解决这种类型的问题.理解和实现比回溯算法更复杂,但运行方式更好:).见:http://en.wikipedia.org/wiki/Dancing_Links

它也是一个更普遍的问题的算法,它被应用于很好地解决数独.

在维基百科上有一篇文章链接,详细介绍了使用约束编程可以解决什么类型的实例:http://4c.ucc.ie/~hsimonis/sudoku.pdf(从这里发现:http://en.wikipedia.org/wiki/Sudoku_algorithms).表4真的很有趣:)

猜你在找的Java相关文章