简体   繁体   English

使用A *算法解决8-puzzle板(Board数据类型工作正常)

[英]Using A* algorithm to solve 8-puzzle boards (Board data type works fine)

Hi I'm using java to create a Solver program that uses the assistance of HeapMinPQ and nodes in order to solve any board based on the "8 puzzle" format. 嗨,我正在使用java创建一个Solver程序,它使用HeapMinPQ和节点的帮助,以解决任何基于“8拼图”格式的板。 I've already created by "Board" data type which uses a two-dimensional array to account for the tiles (and "0" is the blank space). 我已经通过“Board”数据类型创建了它,它使用二维数组来计算tile(而“0”是空格)。 Within my SearchNodes, I have a priority Integer that accounts for the "Manhattan" values (and I'm sure that method works fine). 在我的SearchNodes中,我有一个优先级整数,用于解释“曼哈顿”值(我确信该方法可以正常工作)。 The problem is that I've been trying to make progress, and although my program compiles, it simply gets stuck running without giving the appropriate output (the minimum number of moves required). 问题是我一直在努力取得进步,虽然我的程序编译,但它只是在没有给出适当的输出(所需的最小移动次数)的情况下卡住了。 I guess I'm having difficulty wrapping my head around all of this but this is my code to solve so far... 我想我很难绕过这一切,但这是我到目前为止要解决的代码......

import java.util.Comparator;
public class Solver {
private SearchNode result;

// Helper search node class.
private class SearchNode {
    SearchNode prev; 
    Board value; 
    int moves = 0; 
    int priority;


    public SearchNode(Board board, SearchNode previous) {
        super();
        this.value = board; 
        prev = previous; 
        if (null != previous) { 
            this.moves = previous.moves + 1; 
        } else { 
            this.moves = 0; 
        } 
         // priority = this.value.hamming() + moves; 
         priority = this.value.manhattan() + moves; 

    }
}

/**
 * Finds a solution to the initial board (using the A* algorithm).
 * @param initial initial board.
 */
public Solver(Board initial) {
    SearchNode root = new SearchNode(initial, null); 
    HeapMinPQ<SearchNode> heap = new HeapMinPQ<SearchNode>(new ManhattanOrder()); 
    heap.insert(root);


     Board twin = initial.twin();
     SearchNode twinRoot = new SearchNode(twin, null); 
     HeapMinPQ<SearchNode> twinHeap = new HeapMinPQ<SearchNode>(new ManhattanOrder()); 
     twinHeap.insert(twinRoot); 


     solve(heap, twinHeap);

}

private void solve(HeapMinPQ<SearchNode> heap, HeapMinPQ<SearchNode> twinHeap) { 
     while (!heap.isEmpty() && !twinHeap.isEmpty()) { 
         if (null != perform(heap)) { 
             return; 
         } 


         if (null != perform(twinHeap)) { 
             result = null; 
             return; 
         } 
     } 
 } 


 private SearchNode perform(HeapMinPQ<SearchNode> heap) { 
     SearchNode n = heap.delMin(); 
     if (n.value.isGoal()) { 
         result = n; 
         return result; 
     } 
     for (Board board : n.value.neighbors()) { 
         SearchNode x = new SearchNode(board, n); 
         if (null != n.prev && n.prev.value.equals(board)) { 
             // don't add neighbors that are same as previous board 
             continue; 
         } 
         heap.insert(x); 
     } 
     return null; 
 }

And this is my "twin" method from the "board" data type. 这是我从“板”数据类型的“双胞胎”方法。

public Board twin(){
     int dim = this.length; 
     int[][] copy = this.tiles; 
     if (this.length <= 1) 
         return new Board(copy); 
     // Find zero so that we don't exchange with the blank 
     // This looks like a O(dim^2) algorithm, but on average it should finish 
     // in O(1). 
     int row = 0; 
     int col = 0; 
     int value = 0; 
     int lastValue = tiles[0][0]; 
     zerosearch: for (row = 0; row < dim; row++) { 
         for (col = 0; col < dim; col++) { 
             value = tiles[row][col]; 
             // Check col>0 because swap must occur on same row 
             if (value != 0 && lastValue != 0 && col > 0) 
                 break zerosearch; 
             lastValue = value; 
         } 
     } 
     copy[row][col] = lastValue; 
     copy[row][col - 1] = value; 
     return new Board(copy); 


}

There must be a deep miscalculation that I'm making here and I'm pretty sure it starts at the solve(heap, twinHeap); 我必须在这里做一个深度错误的计算,我很确定它从解决开始(heap,twinHeap); method within the public Solver(Board initial) method. 公共求解器(Board initial)方法中的方法。 Any help would be greatly appreciated. 任何帮助将不胜感激。

here are some tricks to solve 8-puzzle problem: 这里有一些解决8-puzzle问题的技巧:

For Board class: 对于董事会类:

  1. when implementing Board class, it's better to use two integer variables (eg. rowIndex, colIndex) to track where the blank(number 0) is. 在实现Board类时,最好使用两个整数变量(例如rowIndex,colIndex)来跟踪空白(数字0)的位置。 Using self-defined Position class may lead to failure of passing the memory test if you are doing so as an assignment from coursera. 使用自定义的Position类可能会导致无法通过内存测试,如果你这样做是作为一个来自coursera的赋值。

  2. For generating a twin board, pay attention not to swap a number with blank tile whose number is 0. for generating a randomized twin, it's better first to generate two random values range from [0, n*n). 为了生成双板,注意不要用数字为0的空白区块交换数字来生成随机双胞胎,最好先生成两个随机值,范围为[0,n * n)。 then transfer them to row and col index. 然后将它们转移到row和col索引。

  3. When generating neighbors of a board, don't forget to update the blank tile position index. 生成板的邻居时,不要忘记更新空白区块位置索引。

For Solver class: 对于Solver类:

  1. a new private inner class describing a game node is recommended. 建议使用描述游戏节点的新私有内部类。 In this class, we can record the board, moves, and previous node. 在这个类中,我们可以记录板,移动和前一个节点。 and update the Hamming and Manhattan methods which will be used in a Priority Queue to Deque an expected node. 并更新汉明和曼哈顿方法,这些方法将在优先级队列中用于Deque预期节点。

  2. To avoid going into a long-time loop, before inserting a node to a Priority Queue, Do check whether it has already been in the Queue. 为了避免进入长时间循环,在将节点插入优先级队列之前,请检查它是否已经在队列中。

  3. Here are some useful explanation and suggestions from coursera: http://coursera.cs.princeton.edu/algs4/checklists/8puzzle.html 以下是课程中的一些有用的解释和建议: http ://coursera.cs.princeton.edu/algs4/checklists/8puzzle.html

  4. My code is here: My 8-puzzle code not timing optimized for Solver. 我的代码在这里: 我的8-puzzle代码没有针对Solver进行时序优化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM