Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
8拼图A*java实现_Java_Shortest Path_A Star_Sliding Tile Puzzle - Fatal编程技术网

8拼图A*java实现

8拼图A*java实现,java,shortest-path,a-star,sliding-tile-puzzle,Java,Shortest Path,A Star,Sliding Tile Puzzle,有人告诉我,以下8个谜题求解器的*实现是错误的,有人能告诉我哪里是错误的,以及如何纠正它吗 另外:这会在线程“main”java.lang.OutOfMemoryError:java堆空间中引发异常,即使构建进程堆大小设置为2048 下面是Solver.java import java.util.HashSet; import java.util.Set; import java.util.Stack; import java.util.PriorityQueue; public clas

有人告诉我,以下8个谜题求解器的*实现是错误的,有人能告诉我哪里是错误的,以及如何纠正它吗

另外:这会在线程“main”java.lang.OutOfMemoryError:java堆空间中引发异常,即使构建进程堆大小设置为2048

下面是Solver.java

import java.util.HashSet;
import java.util.Set;

import java.util.Stack;
import java.util.PriorityQueue;


public class Solver {
private int moves = 0;
private SearchNode finalNode;
private Stack<Board> boards;


public Solver(Board initial) {
    if (!initial.isSolvable()) throw new IllegalArgumentException("Unsolvable puzzle");

    // this.initial = initial;
    PriorityQueue<SearchNode> minPQ = new PriorityQueue<SearchNode>(initial.size() + 10);

    Set<Board> previouses = new HashSet<Board>(50);
    Board dequeuedBoard = initial;
    Board previous = null;
    SearchNode dequeuedNode = new SearchNode(initial, 0, null);
    Iterable<Board> boards;

    while (!dequeuedBoard.isGoal()) {
        boards = dequeuedBoard.neighbors();
        moves++;

        for (Board board : boards) {
            if (!board.equals(previous) && !previouses.contains(board)) {
                minPQ.add(new SearchNode(board, moves, dequeuedNode));
            }
        }

        previouses.add(previous);
        previous = dequeuedBoard;
        dequeuedNode = minPQ.poll();
        dequeuedBoard = dequeuedNode.current;
    }
    finalNode = dequeuedNode;
}

// min number of moves to solve initial board
public int moves() {
    if (boards != null) return boards.size()-1;
    solution();
    return boards.size() - 1;
}

public Iterable<Board> solution() {
    if (boards != null) return boards;
    boards = new Stack<Board>();
    SearchNode pointer = finalNode;
    while (pointer != null) {
        boards.push(pointer.current);
        pointer = pointer.previous;
    }
    return boards;
}

private class SearchNode implements Comparable<SearchNode> {
    private final int priority;
    private final SearchNode previous;
    private final Board current;


    public SearchNode(Board current, int moves, SearchNode previous) {
        this.current = current;
        this.previous = previous;
        this.priority = moves + current.manhattan();
    }

    @Override
    public int compareTo(SearchNode that) {
        int cmp = this.priority - that.priority;
        return Integer.compare(cmp, 0);
    }


}
public static void main(String[] args) {
    int[][] tiles = {{4, 1, 3},
            {0, 2, 6},
            {7, 5, 8}};



    double start = System.currentTimeMillis();
    Board board = new Board(tiles);
    Solver solve = new Solver(board);
    System.out.printf("# of moves = %d && # of actual moves %d & time passed %f\n, ", solve.moves(), solve.moves, (System.currentTimeMillis() - start) / 1000);


}
}
import java.util.HashSet;
导入java.util.Set;
导入java.util.Stack;
导入java.util.PriorityQueue;
公共类求解器{
私有整数移动=0;
私有搜索节点最终节点;
私人堆叠板;
公共解决方案(董事会首字母){
如果(!initial.isSolvable())抛出新的IllegalArgumentException(“无法解决的难题”);
//this.initial=initial;
PriorityQueue minPQ=新的PriorityQueue(initial.size()+10);
Set previouses=新哈希集(50);
Board dequeuedBoard=初始;
上一个板=空;
SearchNode dequeuedNode=新的SearchNode(初始值,0,null);
可折叠板;
而(!dequeuedBoard.isGoal()){
boards=dequeuedBoard.neights();
移动++;
用于(板:板){
如果(!board.equals(previous)&&!previouses.contains(board)){
添加(新的搜索节点(board、moves、dequeuedNode));
}
}
上一个。添加(上一个);
previous=出列板;
dequeuedNode=minPQ.poll();
dequeuedBoard=dequeuedNode.current;
}
finalNode=dequeuedNode;
}
//求解初始板的最小移动次数
公营机构{
如果(boards!=null)返回boards.size()-1;
溶液();
返回板。尺寸()-1;
}
公共可替代解决方案(){
如果(板数!=null)返回板数;
boards=新堆栈();
SearchNode指针=最终节点;
while(指针!=null){
板。推(指针。电流);
指针=pointer.previous;
}
返回板;
}
私有类SearchNode实现了可比较的{
私有最终int优先级;
私有最终搜索节点;
私人最终董事会电流;
公共SearchNode(当前板、整数移动、上一个SearchNode){
这个电流=电流;
this.previous=先前;
this.priority=moves+current.manhattan();
}
@凌驾
public int compareTo(搜索节点){
int cmp=this.priority-that.priority;
返回整数。比较(cmp,0);
}
}
公共静态void main(字符串[]args){
int[]tiles={{4,1,3},
{0, 2, 6},
{7, 5, 8}};
双启动=System.currentTimeMillis();
板=新板(瓷砖);
解算器解算=新解算器(板);
System.out.printf(“#移动次数=%d和&#实际移动次数%d和经过的时间%f\n,”,solve.moves(),solve.moves,(System.currentTimeMillis()-start)/1000);
}
}
和Board.java,以防万一:

import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;


public final class Board {

    private final int[][] tilesCopy;
    private final int N;

    // cache
    private int hashCode = -1;
    private int zeroRow = -1;
    private int zeroCol = -1;
    private Collection<Board> neighbors;
    /*
     * Rep Invariant
     *      tilesCopy.length > 0
     * Abstraction Function
     *      represent single board of 8 puzzle game
     * Safety Exposure
     *      all fields are private and final (except cache variables). In the constructor,
     * defensive copy of tiles[][] (array that is received from the client)
     * is done.
     */
    public Board(int[][] tiles) {
        //this.N = tiles.length;
        this.N = 3;
        this.tilesCopy = new int[N][N];
        // defensive copy
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if (tiles[i][j] >= 0 && tiles[i][j] < N*N) tilesCopy[i][j] = tiles[i][j];
                else {
                    System.out.printf("Illegal tile value at (%d, %d): "
                            + "should be between 0 and N^2 - 1.", i, j);
                    System.exit(1);
                }
            }
        }
        checkRep();
    }

    public int tileAt(int row, int col) {
        if (row < 0 || row > N - 1) throw new IndexOutOfBoundsException
                ("row should be between 0 and N - 1");
        if (col < 0 || col > N - 1) throw new IndexOutOfBoundsException
                ("col should be between 0 and N - 1");

        return tilesCopy[row][col];
    }

    public int size() {
        return N;
    }

    public int hamming() {
        int hamming = 0;
        for (int row = 0; row < this.size(); row++) {
            for (int col = 0; col < this.size(); col++) {
                if (tileAt(row, col) != 0 && tileAt(row, col) != (row*N + col + 1)) hamming++;
            }
        }
        return hamming;
    }
    // sum of Manhattan distances between tiles and goal
    public int manhattan() {
        int manhattan = 0;

        int expectedRow = 0, expectedCol = 0;
        for (int row = 0; row < this.size(); row++) {
            for (int col = 0; col < this.size(); col++) {
                if (tileAt(row, col) != 0 && tileAt(row, col) != (row*N + col + 1)) {
                    expectedRow = (tileAt(row, col) - 1) / N;
                    expectedCol = (tileAt(row, col) - 1) % N;
                    manhattan += Math.abs(expectedRow - row) + Math.abs(expectedCol - col);
                }
            }
        }
        return manhattan;
    }

    public boolean isGoal() {

        if (tileAt(N-1, N-1) != 0) return false;        // prune

        for (int i = 0; i < this.size(); i++) {
            for (int j = 0; j < this.size(); j++) {
                if (tileAt(i, j) != 0 && tileAt(i, j) != (i*N + j + 1)) return false;
            }
        }

        return true;
    }
    // change i && j' s name
    public boolean isSolvable() {
        int inversions = 0;

        for (int i = 0; i < this.size() * this.size(); i++) {
            int currentRow = i / this.size();
            int currentCol = i % this.size();

            if (tileAt(currentRow, currentCol) == 0) {
                this.zeroRow = currentRow;
                this.zeroCol = currentCol;
            }

            for (int j = i; j < this.size() * this.size(); j++) {
                int row = j / this.size();
                int col = j % this.size();


                if (tileAt(row, col) != 0 && tileAt(row, col) < tileAt(currentRow, currentCol)) {
                    inversions++;
                }
            }
        }

        if (tilesCopy.length % 2 != 0 && inversions % 2 != 0) return false;
        if (tilesCopy.length % 2 == 0 && (inversions + this.zeroRow) % 2 == 0) return false;

        return true;
    }



    @Override
    public boolean equals(Object y) {
        if (!(y instanceof Board)) return false;
        Board that = (Board) y;
        // why bother checking whole array, if last elements aren't equals
        return this.tileAt(N - 1, N - 1) == that.tileAt(N - 1, N - 1) && this.size() == that.size() && Arrays.deepEquals(this.tilesCopy, that.tilesCopy);

    }

    @Override
    public int hashCode() {
        if (this.hashCode != -1) return hashCode;
        // more optimized version(Arrays.hashCode is too slow)?
        this.hashCode = Arrays.deepHashCode(tilesCopy);
        return this.hashCode;
    }

    public Collection<Board> neighbors() {
        if (neighbors != null) return neighbors;
        if (this.zeroRow == -1 && this.zeroCol == -1) findZeroTile();

        neighbors = new HashSet<>();

        if (zeroRow - 1 >= 0)           generateNeighbor(zeroRow - 1, true);
        if (zeroCol - 1 >= 0)           generateNeighbor(zeroCol - 1, false);
        if (zeroRow + 1 < this.size())  generateNeighbor(zeroRow + 1, true);
        if (zeroCol + 1 < this.size())  generateNeighbor(zeroCol + 1, false);

        return neighbors;
    }

    private void findZeroTile() {
        outerloop:
        for (int i = 0; i < this.size(); i++) {
            for (int j = 0; j < this.size(); j++) {
                if (tileAt(i, j) == 0) {
                    this.zeroRow = i;       // index starting from 0
                    this.zeroCol = j;
                    break outerloop;
                }
            }
        }
    }
    private void generateNeighbor(int toPosition, boolean isRow) {
        int[][] copy = Arrays.copyOf(this.tilesCopy, tilesCopy.length);
        if (isRow)  swapEntries(copy, zeroRow, zeroCol, toPosition, zeroCol);
        else        swapEntries(copy, zeroRow, zeroCol, zeroRow, toPosition);

        neighbors.add(new Board(copy));
    }


    private void swapEntries(int[][] array, int fromRow, int fromCol, int toRow, int toCol) {
        int i = array[fromRow][fromCol];
        array[fromRow][fromCol] = array[toRow][toCol];
        array[toRow][toCol] = i;
    }

    public String toString() {
        StringBuilder s = new StringBuilder(4 * N * N);     // optimization?
//      s.append(N + "\n");
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                s.append(String.format("%2d ", tileAt(i, j)));
            }
            s.append("\n");
        }
        return s.toString();
    }

    private void checkRep() {
        assert tilesCopy.length > 0;
    }
}
导入java.util.array;
导入java.util.Collection;
导入java.util.HashSet;
公开期末考试委员会{
私人最终整版[][]瓷砖复印件;
私人终审法院;
//缓存
私有int hashCode=-1;
private int zerorrow=-1;
私有整数zeroCol=-1;
私人收藏邻居;
/*
*重复不变量
*TileCopy.length>0
*抽象功能
*代表单板的8个益智游戏
*安全暴露
*所有字段都是私有的和最终的(缓存变量除外),
*分片[][](从客户端接收的阵列)的防御副本
*完成了。
*/
公共电路板(int[][]瓷砖){
//这.N=瓦片长度;
这个。N=3;
this.tilesCopy=新整数[N][N];
//防御性副本
对于(int i=0;i=0和&tiles[i][j]N-1)抛出新的IndexOutOfBoundsException
(“行应介于0和N-1之间”);
如果(col<0 | | col>N-1)抛出新的IndexOutOfBoundsException
(“col应介于0和N-1之间”);
返回瓷砖复制[行][列];
}
公共整数大小(){
返回N;
}
公共卫生署署长{
int-hamming=0;
对于(int row=0;rowint[][] copy = Arrays.copyOf(this.tilesCopy, tilesCopy.length);
copy == this.tolesCopy // false
copy[0] == this.tilesCopy[0] // true
copy[1] == this.tilesCopy[1] // true
copy[2] == this.tilesCopy[2] // true
private void generateNeighbor(int toPosition, boolean isRow) {
    Board board = new Board(this.tilesCopy);
    if (isRow)  swapEntries(board.tilesCopy, zeroRow, zeroCol, toPosition, zeroCol);
    else        swapEntries(board.tilesCopy, zeroRow, zeroCol, zeroRow, toPosition);

    neighbors.add(board);
}