Java 幻灯片拼图算法中的无限循环
试图写一个解决幻灯片难题的算法,我遇到了一些问题,我想我应该来这里寻求建议。这是普林斯顿算法,第1部分课程顺便说一句 因此,我将尝试解释逻辑,然后显示代码。基本上,我有一个最小优先级的搜索节点队列。每个搜索节点都有一个棋盘、一个前一个棋盘、到达该棋盘的移动次数和曼哈顿优先级(移动次数+曼哈顿距离) 每次通过while(true)循环都会删除最小节点(最小优先级),并添加新节点,这些节点的前一个节点是已删除节点,板是与已删除节点相邻的板(移动1个),并且移动1个比前一个节点大 最后,被删除的节点应该具有已求解的电路板,然后通过循环求解节点的先前节点来找到最短路径。但这永远不会发生。我不知道我的逻辑是否有缺陷,或者我的代码是否有问题。但我一直想弄明白这一点很长一段时间,却一事无成Java 幻灯片拼图算法中的无限循环,java,algorithm,infinite-loop,Java,Algorithm,Infinite Loop,试图写一个解决幻灯片难题的算法,我遇到了一些问题,我想我应该来这里寻求建议。这是普林斯顿算法,第1部分课程顺便说一句 因此,我将尝试解释逻辑,然后显示代码。基本上,我有一个最小优先级的搜索节点队列。每个搜索节点都有一个棋盘、一个前一个棋盘、到达该棋盘的移动次数和曼哈顿优先级(移动次数+曼哈顿距离) 每次通过while(true)循环都会删除最小节点(最小优先级),并添加新节点,这些节点的前一个节点是已删除节点,板是与已删除节点相邻的板(移动1个),并且移动1个比前一个节点大 最后,被删除的节点应
我应该提到,每个幻灯片都是二维数组,其中0对应于空白空间。 以下是节点类:
private class Node {
Node previous;
Board board;
int moves;
int priority;
Node(Node previous, Board board, int moves) {
this.previous = previous;
this.board = board;
this.moves = moves;
priority = moves + board.manhattan();
}
}
这是我用来比较节点的比较器。如果一个节点的优先级较低,则该节点比另一个节点小
// compares nodes based on their Manhattan priority
private Comparator<Node> priority() {
return (o1, o2) -> {
return Integer.compare(o1.priority, o2.priority);
};
}
//根据节点的优先级比较节点
专用比较器优先级(){
返回(o1,o2)->{
返回整数。比较(o1.priority,o2.priority);
};
}
这是一个解算器构造器,用来解决幻灯片难题。这目前假设这个难题是可以解决的。while(true)循环给了我很多问题,我不知道为什么
// find solution to the initial board using A* algorithm
public Solver(Board initial) {
// define the first Node
Node first = new Node(null, initial, 0);
// enqueue neighbors into MinPQ
MinPQ<Node> pq = new MinPQ<>(priority());
for (Board board : first.board.neighbors()) {
pq.insert(new Node(first, board, 1));
}
while (true) {
// delete min node
Node min = pq.delMin();
// if it is the goal board, stop
if (min.board.isGoal()) {
break;
}
// add neighbors to pq
for (Board board : min.board.neighbors()) {
Node neighborNode = new Node(min, board, min.moves + 1);
// don't add grandfather nodes
if (!min.previous.board.equals(neighborNode.board)) {
pq.insert(neighborNode);
}
}
}
}
//使用*算法找到初始电路板的解决方案
公共解决方案(董事会首字母){
//定义第一个节点
Node first=新节点(null,initial,0);
//让邻居排队进入MinPQ
MinPQ pq=新的MinPQ(优先级());
for(Board-Board:first.Board.neights()){
pq.插入(新节点(第一个,电路板,1));
}
while(true){
//删除最小节点
节点最小值=pq.delMin();
//如果是目标板,停止
if(min.board.isGoal()){
打破
}
//将邻居添加到pq
用于(板:min.Board.neights()){
节点邻居节点=新节点(最小,线路板,最小移动+1);
//不要添加外祖父节点
如果(!min.previous.board.equals(nextorNode.board)){
pq.插入(相邻节点);
}
}
}
}
第一步是确保Board.isGoal()
按预期工作-如果它被破坏,您的循环将永远不会结束。第二步是通过一个调试器来运行这个程序,并按照算法来查看错误所在。如果当前板位置与以前的板位置匹配,你会怎么做?只有在重复位置时才能得到无限循环。您可能需要检测重复的位置并采取措施避免循环。我还将删除第一个for循环,并将第一个节点直接放置在队列中,移动次数为0。如果您的初始棋盘已解算,这将允许您按预期在0步内完成。