有几天我试图写一个强力算法来解决数独,我的问题是我从来没有真正让算法100%工作,有人可以指导我并给予一些帮助吗?
算法位于Square类,递归函数。
public abstract class Square {
private Square next;
private Box box;
private Row row;
private Columne columne;
private int value;
Square(int value, Box box, Row row, Columne columne) {
this.value = value;
this.box = box;
this.row = row;
this.columne = columne;
}
void setNumberMeAndTheRest(Board board) {
if(getNext() == null) {
System.out.println("next == null");
for(int i = 1; i <= board.getDimension(); i++) {
if(legalValue(i)) {
setValue(i);
}
}
board.saveSolution();
return;
} else {
if(this instanceof DefinedSquare) {
getNext().setNumberMeAndTheRest(board);
} else {
for(int i = 1; i <= board.getDimension(); i++) {
if(legalValue(i)) {
setValue(i);
getNext().setNumberMeAndTheRest(board);
}
}
return;
}
}
}
int getValue() {
return value;
}
void setValue(int value) {
this.value = value;
}
void setNext(Square next) {
this.next = next;
}
public Square getNext() {
return next;
}
/**
* Checks if value is legal in box, row and column.
* @param value to check.
* @return true if value is legal, else false.
*/
boolean legalValue(int value) {
if(box.legalValue(value) && row.legalValue(value) && columne.legalValue(value)) {
return true;
}
return false;
}
答案 0 :(得分:2)
我认为你的问题可能就在这里
for(int i = 1; i <= board.getDimension(); i++) {
if(legalValue(i)) {
setValue(i);
getNext().setNumberMeAndTheRest(board);
}
}
如果legalValue(i)返回i的当前状态的真实独立,那么您将回溯跟踪,否则,您不会回溯
大多数回溯看起来像是像htis这样的东西
for(int i = 1; i <= board.getDimension(); i++) {
if(legalValue(i)) {
setValue(i);
// boolean indicating whether solution was found
if(getNext().setNumberMeAndTheRest(board))
return true;
else
unsetValue(i)
}
}
我们需要更多代码来了解当square i已经设置时,legalValue是否返回false
试试看我是否在正确的轨道上或发布所有代码
System.out.println("STARTING ITERATION")
for(int i = 1; i <= board.getDimension(); i++) {
if(legalValue(i)) {
System.out.println("GOING " + i)
setValue(i);
getNext().setNumberMeAndTheRest(board);
}
}
System.out.println("ENDING ITERATION")
如果它填满网格,然后在没有回溯的情况下停止,你的问题是你调用setValue(i)然后调用legalValue(i + 1)并返回false 因为该值是alraedy set,而不是因为它不合法。如果是这样,那么在reucrsion之后你需要一个等价的'unset'
答案 1 :(得分:1)
从快速查看算法看起来,它似乎只在每个方块中尝试一个可能的值。当它到达一个无法找到合法价值的广场时,它就会放弃。它需要一些回溯机制,并在之前填充的方块中尝试替代法律价值。
举个例子,这是一个迷你4x4拼图:
1 |
| 2
---------
| 4
3 |
根据我的判断,你的算法会远远地退出:
2 1 | 3 X
| 2
---------
| 4
3 |
不应该退出,而是应该返回并更改已插入的2个值中的任何一个。