java:广度优先遍历迷宫回溯

发布于 2024-12-25 02:55:02 字数 1536 浏览 5 评论 0原文

我正在尝试为迷宫实现广度优先遍历。这是我到目前为止使用链表的代码,但我不确定它是否是广度优先搜索。这是正确的方法吗?有什么建议、意见吗?

    public boolean traverseBreadth(){
    //traverse the floor from entrance to exit
    //stepping only on red tiles
    steps = new LinkedList<Tile>();
    possibleSteps = new LinkedList<Tile>();
     //reset markings
     reset();
    //push the entrance onto the stack
    entrance.setVisited();
    steps.add(entrance);

    System.out.println("add " + entrance);
    nextMoves(entrance);
    //keep going as long as we have a possibility to move
    //and we haven't reached the end yet
    while (!possibleSteps.isEmpty()&& (!possibleSteps.getLast().equals(exit)))
    {   
        Tile x = possibleSteps.removeLast();

        x.setMarked();   //walked on that square
        steps.add(x);  //walk to that square
        System.out.println("Walked to the square  " + x);
        //now figure out where you can walk from this square
        nextMoves(x);
        try {
               Thread.currentThread().sleep(1000);
               }
             catch (InterruptedException e) {
               e.printStackTrace();
               }





    }
    if (possibleSteps.getLast().equals(exit)){
        steps.push(possibleSteps.removeLast());
        System.out.println("made it from entrance to exit");
        System.out.println(steps.toString());
        return true;
    }
    else 
    {   JOptionPane.showMessageDialog(null,"sorry can't reach the exit");
        return false;
    }

}

I am trying to implement a breadth first traversal for a maze. This is the code I have so far using a linked list but I am not sure if it is searching breadth first. Is this the proper way to do it? any suggestions, comments?

    public boolean traverseBreadth(){
    //traverse the floor from entrance to exit
    //stepping only on red tiles
    steps = new LinkedList<Tile>();
    possibleSteps = new LinkedList<Tile>();
     //reset markings
     reset();
    //push the entrance onto the stack
    entrance.setVisited();
    steps.add(entrance);

    System.out.println("add " + entrance);
    nextMoves(entrance);
    //keep going as long as we have a possibility to move
    //and we haven't reached the end yet
    while (!possibleSteps.isEmpty()&& (!possibleSteps.getLast().equals(exit)))
    {   
        Tile x = possibleSteps.removeLast();

        x.setMarked();   //walked on that square
        steps.add(x);  //walk to that square
        System.out.println("Walked to the square  " + x);
        //now figure out where you can walk from this square
        nextMoves(x);
        try {
               Thread.currentThread().sleep(1000);
               }
             catch (InterruptedException e) {
               e.printStackTrace();
               }





    }
    if (possibleSteps.getLast().equals(exit)){
        steps.push(possibleSteps.removeLast());
        System.out.println("made it from entrance to exit");
        System.out.println(steps.toString());
        return true;
    }
    else 
    {   JOptionPane.showMessageDialog(null,"sorry can't reach the exit");
        return false;
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情丝乱 2025-01-01 02:55:02

这不是广度优先搜索 - 这是深度优先。

有 2 个地方显然是深度优先的,

  • 您从边界的末尾(可能的图块)而不是开头删除。
  • 您没有遍历层次结构(父到子)来重建遍历路径,只有一个带有图块的“路径”。因此,深度优先。

需要更改的内容:

  • 将 LinkedList 更改为 Dictionary。字典的键将是图块,值将是图块的父级。用它来重建你的最终路径。
  • 您的“moveNext”功能可能是正确的。确保它被推到列表的末尾。
  • 不要从 MaybeSteps 中弹出 (getLast())。 possibleSteps 应该是先进先出队列。检索可能步骤的第一个图块(这将首先探索最接近起点的图块)。

需要改进的地方:

  • 不要使用 Tile 来跟踪探索,而是使用 Set(称为 ExploredTile)来放置已遍历的图块),
  • 使用 Queue 而不是 List。

一些 C#/伪代码(因为我不在 IDE)

Dictionary<Tile,Tile> path = ...;
Queue<Tile> frontier = ...;
Set<Tile> explored = ...;

path[start] = null;

while(frontier.Count > 0){
    var tile = frontier.Dequeue();

    if(explored.Contains(tile)){
        continue;
    }
    explored.add(tile);

    if (Tile == Exit){
        rebuildPath(Exit);
    }else{
        for (Tile t in Tile.neighbours){
            if (!explored.Contains(t)){
                frontier.Enqueue(t);
                path[t] = tile; // Set the path hierarchy
            }
        }
    }
}

RebuildPath

LinkedList<Tile> finalPath = ...;

Tile parent = path[exitTile];
finalPath.push(exitTile);

while(parent != null){
    finalPath.push(parent);
    parent = path[parent];
}

finalPath.reverse();

希望我做对了...:)

This isn't a breadth first search - this is depth first.

There are 2 places that are obviously depth first

  • you remove from the end of the frontier (possibleTiles), not the beginning.
  • you do not have a traversal hierarchy (parent to child) to rebuild the traversal path, only a single "path" with tiles. Therefore, it is depth first.

Things to change:

  • instead of LinkedList, change that to Dictionary. The key of the dictionary will be the tile, and the value will be the tile's parent. Use this to reconstruct your final path.
  • your "moveNext" function is probably right. Make sure it is pushing to the end of the List.
  • do not pop (getLast()) from PossibleSteps. PossibleSteps should be a First-In-First-Out queue. Retrieve the first Tile of PossibleSteps (this will explore the tiles closest to the start first).

Things to improve:

  • instead of using Tile to track exploration, use a Set (call it ExploredTile) where you put tiles that you have traversed)
  • use a Queue instead of List.

Some C#/Pseudo Code (cuz I'm not at an IDE)

Dictionary<Tile,Tile> path = ...;
Queue<Tile> frontier = ...;
Set<Tile> explored = ...;

path[start] = null;

while(frontier.Count > 0){
    var tile = frontier.Dequeue();

    if(explored.Contains(tile)){
        continue;
    }
    explored.add(tile);

    if (Tile == Exit){
        rebuildPath(Exit);
    }else{
        for (Tile t in Tile.neighbours){
            if (!explored.Contains(t)){
                frontier.Enqueue(t);
                path[t] = tile; // Set the path hierarchy
            }
        }
    }
}

RebuildPath

LinkedList<Tile> finalPath = ...;

Tile parent = path[exitTile];
finalPath.push(exitTile);

while(parent != null){
    finalPath.push(parent);
    parent = path[parent];
}

finalPath.reverse();

Hopefully I got it right... :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文