Java 幻灯片拼图算法中的无限循环

Java 幻灯片拼图算法中的无限循环,java,algorithm,infinite-loop,Java,Algorithm,Infinite Loop,试图写一个解决幻灯片难题的算法,我遇到了一些问题,我想我应该来这里寻求建议。这是普林斯顿算法,第1部分课程顺便说一句 因此,我将尝试解释逻辑,然后显示代码。基本上,我有一个最小优先级的搜索节点队列。每个搜索节点都有一个棋盘、一个前一个棋盘、到达该棋盘的移动次数和曼哈顿优先级(移动次数+曼哈顿距离) 每次通过while(true)循环都会删除最小节点(最小优先级),并添加新节点,这些节点的前一个节点是已删除节点,板是与已删除节点相邻的板(移动1个),并且移动1个比前一个节点大 最后,被删除的节点应

试图写一个解决幻灯片难题的算法,我遇到了一些问题,我想我应该来这里寻求建议。这是普林斯顿算法,第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步内完成。