Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.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
Java DFS算法-8字谜或nXn游戏_Java_Algorithm - Fatal编程技术网

Java DFS算法-8字谜或nXn游戏

Java DFS算法-8字谜或nXn游戏,java,algorithm,Java,Algorithm,我想解一个DFS算法。它是关于游戏8个拼图或nxn拼图。开始时,我有两个数组,如(零表示一个空字段): 这个数组进入我的通用DFS类,它工作得很好。我正确地将它用于其他任务。但是为了完整起见,这里是我的DFS类的basic部分: private static boolean search(State node, State target) { if (node.equals(target)) return true; for (State neighbour :

我想解一个DFS算法。它是关于游戏
8个拼图
nxn
拼图。开始时,我有两个数组,如(零表示一个空字段):

这个数组进入我的通用DFS类,它工作得很好。我正确地将它用于其他任务。但是为了完整起见,这里是我的DFS类的
basic
部分:

private static boolean search(State node, State target) {
    if (node.equals(target))
        return true;

    for (State neighbour : node.getNeighbours()) {
        if (!visited.contains(neighbour)) {
            predMap.put(neighbour,node);
            visited.add(neighbour);
            if (search(neighbour, target)){
              return true;
            }
        }
    }
    return false;
}
因此,首先,my
start
数组将作为第一个参数传递,my
target
数组将作为第二个参数传递

在我的
State
类中,我想实现
getneights()
方法,该方法应该返回所有可能的状态。在第一轮中,类似于:

First:
|0|1|2|
|4|5|3|
|7|8|6|

Second (rotated zero):
|1|0|2|
|4|5|3|
|7|8|6|

etc...
这是我的问题。你怎么能做到?它适用于前4个操作,但我得到一个异常(零或空字段不在异常位置上,或者有两个零)。怎么了

@Override
public List<State> getNeighbours() {
    List<State> neighbours = new LinkedList<>();

    // possibles moves...
    final int startX = (freeX - 1 < 0) ? freeX : freeX - 1;
    final int startY = (freeY - 1 < 0) ? freeY : freeY - 1;
    final int endX = (freeX + 1 > N - 1) ? freeX : freeX + 1;
    final int endY = (freeY + 1 > N - 1) ? freeY : freeY + 1;

    for (int row = startX; row <= endX; row++) {
        for (int column = startY; column <= endY; column++) {
            int tmp = board[row][column];
            board[row][column] = board[freeX][freeY];
            board[freeX][freeY] = tmp;

            // Just show the table...
            System.out.println("=== BEFORE ===");
            for (int[] x : board) {
                System.out.println(Arrays.toString(x));
            }

            neighbours.add(new State(board, freeX + row, freeY + column));

            board[freeX][freeY] = board[row][column];
            board[row][column] = tmp;

            // Just show the table...
            System.out.println("=== AFTER ===");
            for (int[] x : board) {
                System.out.println(Arrays.toString(x));
            }
        }
    }

    return neighbours;    
}
@覆盖
公众名单{
列表邻居=新建LinkedList();
//可能的移动。。。
最终整数startX=(freeX-1<0)?freeX:freeX-1;
最终整数起始=(freeY-1<0)?freeY:freeY-1;
最终整数endX=(freeX+1>N-1)?freeX:freeX+1;
最终整数endY=(freeY+1>N-1)?freeY:freeY+1;

对于(int row=startX;row我检查了您的代码,导致该异常的原因是,每个州都共享板阵列。您应该制作该阵列的深度副本,您可以尝试以下代码:

public Board(int[][] board, int x, int y){
    if (board[x][y]!=0)
        throw new IllegalArgumentException("Field (" +x+","+y+") must be free (0).");
    this.board = new int[board.length][board[0].length];
    for (int i = 0; i < this.board.length; i++)
        for (int j = 0; j < this.board[i].length; j++)
            this.board[i][j] = board[i][j];
    this.freeX = x;
    this.freeY = y;
    this.N = board.length;
}
公共板(int[][]板,int x,int y){
如果(板[x][y]!=0)
抛出新的IllegalArgumentException(“字段(“+x+”,“+y+”)必须是自由的(0)。”;
this.board=new int[board.length][board[0].length];
for(int i=0;i
但您的代码中仍然存在一些问题:

  • DFS可能会多次递归并导致堆栈溢出--您应该增加堆栈大小(
    -Xss100m
    对我有效)。增加堆栈大小后,您的代码可以输出解决方案,但需要197144个步骤

  • 事实上,正如您所看到的,DFS只输出有效的解决方案(如果您的代码正确),而不是最佳解决方案。您应该尝试BFS


  • 你能把你所有的代码都发出去吗?或者发一个github repo的url吗?当然。我编辑了我的帖子。最后是一个链接。该要点中没有给出状态代码。它只是一个界面,但我更新了gistPlease看看我的答案…如果你还有问题,请随时留下评论。。。
    public Board(int[][] board, int x, int y){
        if (board[x][y]!=0)
            throw new IllegalArgumentException("Field (" +x+","+y+") must be free (0).");
        this.board = new int[board.length][board[0].length];
        for (int i = 0; i < this.board.length; i++)
            for (int j = 0; j < this.board[i].length; j++)
                this.board[i][j] = board[i][j];
        this.freeX = x;
        this.freeY = y;
        this.N = board.length;
    }