数独计算程序

数独是什么,就不解释了。

下面给出一个数独的截图

 
计算规则,其实对每个未确定的空格,保证所在的行唯一,列唯一和所在小九宫格唯一就好了。
 
直观的解决方法是暴力+回溯。
但是暴力+回溯可能带来的问题是,效率不高。
实际计算过程中,可以进行剪枝,即去除一部分无效运算。则面临2个问题。
1. 如何确定下一个对象。 即有这么多需要确定的空格,如何确定那些空格的优先级
2. 在面临每个空格都有多个选择的时候,如何选择。
上述两个问题是我们剪枝的原则。
 
对于上述数独。我们可以定义一个模型为:
class SudokuInstance{
   SudokuCell[][] cells;

   public SudokuInstance(int[][] sudoku){
      init(sudoku);
   }
  
   void init(int[][] sudoku){
       initCells(sudoku);
       adjustCells();
   }

   void initCells(int[][] sudoku){
      cells = new SudokuCell[9][9];   
      for(int i=0;i<sudoku.length;i++){
          for(int j=0;j<sudoku.length;j++){
               if(sudoku[i][j] == 0){
                   cells[i][j] = new SudokuCell(i,j,sudoku[i][j]); 
               }else{
                   cells[i][j] = new SudokuCell(i,j);
               }
       }
    }
    void adjustCells(){
        //1. reduceCandidates
        //2. checkFamliyUnique()
     }
   }



   public static class SudokuCell{
       private int x;
       private int y;
       private List<Integer> candidates;
   
       private int val;
       private SudokuFamliy famliy;       

       public SudokuCell(int x,int y, int val){
            this.x=x;
            this.y=y;
            this.val=val;
            this.candidates=new LinkedList<>();
            this.famliy = SudokuFamliy.vauleOf(x,y);     
       }

       public SudokuCell(int x,int y, int val){
            this.x=x;
            this.y=y;
            this.candidates=new LinkedList<>();
            for(int i=1;i<10;i++){
              this.candidates.add(i);
            }
            this.famliy = SudokuFamliy.vauleOf(x,y);     
        }

    }
}

模型定义好以后,后续主要是调整堆栈。以及剪枝策略。

剪枝策略是选出候选最少的进行枚举。

原文地址:https://www.cnblogs.com/lykm02/p/5177809.html