数独求解

本文介绍了一种使用AI算法解决数独游戏的方法,包括数独的基本规则、常用推理规则以及实现步骤。通过实现一个解决数独问题的算法,展示了如何通过逻辑推理将数独数据中的剩余数字全部推导出来。

题目标题:

  • 数独推理

  • 数独(すうどく,Sudoku)是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫内的数字均含1-9,不重复。每一道合格的数独谜题都有且仅有唯一答案,推理方法也以此为基础,任何无解或多解的题目都是不合格的。

  • 常用推理规则:

  • 1.根据行数据,可以获得需要推理的空格中可能的数据N1..Nn。再根据列数据,判断可能的数据中只有Nm满足条件,因为出Nm外的其他数据在列数据中都已经存在。

  • 2.根据列数据,可以获得需要推理的空格中可能的数据N1..Nn。再根据行数据,判断可能的数据中只有Nm满足条件,因为出Nm外的其他数据在行数据中都已经存在。

  • 3.根据粗线宫数据,可以获得需要推理的空格中可能的数据N1..Nn。再根据行数据或列数据,判断可能的数据中只有Nm满足条件,因为出Nm外的其他数据在行数据或列数据中都已经存在。

  • 要求把数独数据中剩余的数字全部推理完毕。数独数据中为0的即为需要推理的数字。用例保证给定的数据均可使用给定的规则推理完毕。

详细描述:

  • 接口说明

 

/*
 Description  
          推理数独数字
 Input Param 
          sdata  需要推理的数独数据
 Return Value
          推理成功的数组
          失败或其他异常返回null
 */
 public static  int[][] sudokuDataSolve(int[][] sdata)
 {
  
  return null;
 }

 

 

代码如下:

  1   2 
  3 
  4 public final class Demo {
  5 
  6 
  7     public static  int[][] sudokuDataSolve(int[][] sdata)
  8     {
  9         int count=getEmptyNumCount(sdata);
 10         int[][] EmpNumList=getEmptyNumList(sdata,count);
 11         int k=0;
 12         int i,j;
 13         while(k<count)
 14         {
 15             i=EmpNumList[k][0];
 16             j=EmpNumList[k][1];
 17             if(sdata[i][j]==0)
 18             {
 19                 sdata[i][j]=1;
 20             }else{
 21                 if(sdata[i][j]<9){
 22                     if(!isVaild(sdata,i,j))
 23                     {
 24                         sdata[i][j]++;
 25                     }else
 26                     {
 27                         k++;
 28                     }
 29                 }else if(sdata[i][j]==9)
 30                 {
 31                     if(!isVaild(sdata,i,j))
 32                     {
 33                         if(k==0)
 34                         {
 35                             System.out.println("This problem can not be solved");
 36                             
 37                         }else
 38                         {
 39                             do
 40                             {
 41                                 k--;
 42                                 sdata[i][j]=0;
 43                                 i=EmpNumList[k][0];
 44                                 j=EmpNumList[k][1];
 45                             }while(sdata[i][j]==9);
 46                             sdata[i][j]++;
 47                         }
 48                         
 49                     }else
 50                     {
 51                         k++;
 52                     }
 53                 }
 54             }
 55             
 56         }
 57         
 58         return sdata;
 59     }
 60     
 61     
 62     public static boolean checkRow(int [][] sudokuDataSolve,int i,int j)
 63     {
 64         if(sudokuDataSolve[i][j]==0)
 65         {
 66             return true;
 67         }else
 68         {
 69             for(int k=0;k<9;k++)
 70             {
 71                 if(k!=j&&sudokuDataSolve[i][j]==sudokuDataSolve[i][k])
 72                 {
 73                     return false;
 74                 }
 75             }    
 76             return true;
 77         }
 78         
 79     }
 80     
 81     public static boolean checkCol(int [][] sudokuDataSolve,int i,int j)
 82     {
 83         if(sudokuDataSolve[i][j]==0)
 84         {
 85             return true;
 86         }else
 87         {
 88             for(int k=0;k<9;k++)
 89             {
 90                 if(k!=i&&sudokuDataSolve[i][j]==sudokuDataSolve[k][j])
 91                 {
 92                     return false;
 93                 }
 94             }    
 95             return true;
 96         }
 97     
 98     }
 99     public static boolean checkCell(int [][] sudokuDataSolve,int i,int j)  
100     {
101         if(sudokuDataSolve[i][j]==0)
102         {
103             return true;
104         }else
105         {
106             for(int m=(i/3)*3;m<(i/3)*3+3;m++)
107             {
108                 for(int n=(j/3)*3;n<(j/3)*3+3;n++)
109                 {
110                     if((m!=i||n!=j)&&sudokuDataSolve[i][j]==sudokuDataSolve[m][n])
111                     {
112                         return false;
113                     }
114                 }
115             }
116             return true;
117         }
118    }
119     public static boolean isVaild(int [][] sudokuDataSolve,int i,int j)
120     {
121         if(checkRow(sudokuDataSolve,i,j)&&checkCol(sudokuDataSolve,i,j)&&checkCell(sudokuDataSolve,i,j))
122         {
123             return true;
124         }else
125         {
126             return false;
127         }
128         
129     }
130     public static  int getEmptyNumCount(int[][] sudokuDataSolve)
131     {
132         int count=0;
133         for(int i=0;i<9;i++)
134             for(int j=0;j<9;j++)
135             {
136                 if(sudokuDataSolve[i][j]==0)
137                     count++;
138             }
139         return count;
140     }
141     public static  int[][] getEmptyNumList(int[][] sudokuDataSolve,int count)
142     {
143         int k=0;
144         int[][] EmpNumList=new int[count][2];
145         for(int i=0;i<9;i++)
146         {
147             for(int j=0;j<9;j++)
148             {
149                 if(sudokuDataSolve[i][j]==0)
150                 {
151                     EmpNumList[k][0]=i;
152                     EmpNumList[k][1]=j;
153                     k++;
154                 }
155                 
156             }
157         }
158         return EmpNumList;
159     }    
160 
161 }

 原文来自个人博客http://poeticliving.com/archives/155

 

转载于:https://www.cnblogs.com/poeticliving/p/3233171.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值