数独逻辑求解算法 (Java)
我决定为我的数独应用程序编写一个逻辑求解算法。我写的内容适用于有限数量的网格值,但递归很快就停止了。
我的方法的作用: addToThirdDimension():三维数组存储可以放入逻辑网格[x][y]处的网格值中的任何可能的值。该方法刷新三维数组。它通过测试每个网格索引中的值 1-9 来实现此目的,如果有效,则会将该数字添加到数组中。如果不是,则将该值设置为零。
checkValues():检查三维网格中还剩下多少种可能性。它遍历逻辑网格并返回网格中非零值的数量。
checkSingleValue(int row, int col):检查logicGrid[row][col]中是否只剩下一个值(如果剩下一个值,则它是[row]处的网格元素的唯一可能,col])。它返回该网格位置中的非零值的数量。
getSingleValue(int row, int col):返回logicGrid[row][col]中剩下的单个数字。
immutableValues:一个二维布尔数组,存储特定网格元素是否不可变。如果它是不可变的,则解决方法不应触及它。
public boolean solveWithLogic(){
addToThirdDimension();
if(checkValues() == 0){
return true;
}
for(int row = 0; row < 9; row++){
for(int col = 0; col < 9; col++){
if(!immutableValues[row][col]){
if(checkSingleValue(row, col) == 1){
sGrid[row][col] = getSingleValue(row, col);
setValues[row][col] = true;
addToThirdDimension();
}
}
}
}
if(checkValues() != 0){
solveWithLogic();
} else{
return true;
}
return false;
}
我看不出我哪里出了问题。经过一定次数的尝试后,即使应该有更多的可能性, checkValues 也会返回 0。这是 addToThirdDimension() 的代码,因为我确信如果有问题,就在这里。
sGrid 是存储拼图值的主要二维整数数组。
public void addToThirdDimension(){
logicGrid = new int[9][9][9];
for(int x = 0; x < 9; x++){
for(int y = 0; y < 9; y++){
for(int z = 0; z < 9; z++){
logicGrid[x][y][z] = z + 1;
}
}
}
int[][] temp1 = sGrid;
for(int row = 0; row < 9; row++){
for(int col = 0; col < 9; col++){
if(setValues[row][col]){
for(int i = 0; i < 9; i++){
logicGrid[row][col][i] = 0;
}
} else{
for(int i = 1; i <= 9; i++){
temp1[row][col] = i;
if(!isColumnValid(col, temp1) && !isRowValid(row, temp1) &&
!isQuadrantValid(row, col, temp1){
logicGrid[row][col][i-1] = 0;
}
}
}
temp1[row][col] = sGrid[row][col];
}
}
}
目前该代码效率还不太高。我希望在开始最小化求解时间之前让它发挥作用。
I decided to write a logic solving algorithm for my Sudoku application. What I wrote works for a limited amount of grid values, but then the recursion stops way too soon.
What my methods do:
addToThirdDimension(): A three dimensional array stores any possible values that can be put into the grid value at logicGrid[x][y]. This method refreshes the three dimensional array. It does this by testing values 1-9 in every grid index, and if it's valid, it adds that number to the array. If not, it sets that value to zero.
checkValues(): Checks how many possibilities are left in the three dimensional grid. It goes through the logicGrid and returns the number of non-zero values are in the grid.
checkSingleValue(int row, int col): Checks logicGrid[row][col] to see if there is one and only one value left in there (If there is one value left, it is the only possibility for the grid element at [row, col]). It returns the amount of non-zero values that are in that grid location.
getSingleValue(int row, int col): Returns the single number that's left in logicGrid[row][col]
immutableValues: A two dimensional boolean array that stores whether or not a specific grid element is immutable or not. If it is immutable, the solve method should not touch it.
public boolean solveWithLogic(){
addToThirdDimension();
if(checkValues() == 0){
return true;
}
for(int row = 0; row < 9; row++){
for(int col = 0; col < 9; col++){
if(!immutableValues[row][col]){
if(checkSingleValue(row, col) == 1){
sGrid[row][col] = getSingleValue(row, col);
setValues[row][col] = true;
addToThirdDimension();
}
}
}
}
if(checkValues() != 0){
solveWithLogic();
} else{
return true;
}
return false;
}
I cannot see where I am going wrong. After a certain number of tries, checkValues returns 0 even though there should be more possibilities. Here is the code for addToThirdDimension() as I am sure that if something is wrong, it is here.
sGrid is the main two-dimensional integer array that stores the values for the puzzle.
public void addToThirdDimension(){
logicGrid = new int[9][9][9];
for(int x = 0; x < 9; x++){
for(int y = 0; y < 9; y++){
for(int z = 0; z < 9; z++){
logicGrid[x][y][z] = z + 1;
}
}
}
int[][] temp1 = sGrid;
for(int row = 0; row < 9; row++){
for(int col = 0; col < 9; col++){
if(setValues[row][col]){
for(int i = 0; i < 9; i++){
logicGrid[row][col][i] = 0;
}
} else{
for(int i = 1; i <= 9; i++){
temp1[row][col] = i;
if(!isColumnValid(col, temp1) && !isRowValid(row, temp1) &&
!isQuadrantValid(row, col, temp1){
logicGrid[row][col][i-1] = 0;
}
}
}
temp1[row][col] = sGrid[row][col];
}
}
}
The code isn't too efficient at the moment. I want to get it working before I start minimizing solve times.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我要做的第一件事是创建一个 SudukoCell 对象,在其中存储您可能的值。然后创建一个带有 SudukoCells 二维数组的 SudukoBoard。还给它一个 SudukoAreas 数组。一个区域用于行,一个区域用于列,一个区域用于块。
适当添加您的数独细胞。
这将帮助你巩固你的跑腿工作并防止愚蠢的错误。
然后,每次解出一个数字时,您都可以转到每个区域中的单元格,并从中删除您解出的数字。
The first thing I would do is create a SudukoCell object that stores your possible values in it. Then create a SudukoBoard with a 2d array of SudukoCells. Also give it an array of SudukoAreas. One area for rows, one area for cols, and one area for blocks.
Add your suduko cells appropriately.
This will help you consolidate your legwork and prevent silly mistakes.
then every time you solve a number, you can go to the cells in each of its areas and remove the number you solved from them.