【问题标题】:My pathfinder has problems finding the shortest path我的探路者无法找到最短路径
【发布时间】:2010-06-29 21:17:54
【问题描述】:

我在使用探路者时遇到了问题(这是我的第一个,所以这是意料之中的):它并不总是采用最短的方式。例如,如果我想向下走一格,路径将是:向左一格,向下一格,向右一格。

public void getSquares(){
        actPath = new String[Map.x][Map.y];
        isDone = new boolean[Map.x][Map.y];
        squareListener = new SquareListener[Map.x][Map.y];
        getSquares2(x,y,0,new String());
    }
    public void getSquares2(int x, int y, int movesused, String path){
        boolean test1 = false;
        boolean test2 = false;
        test1 = (x < 0 || y < 0 || x > Map.x || y > Map.y);
        if(!test1){
            test2 = Map.landTile[y][x].masterID != 11;
        }
        if(movesused <= 6 && (test1 || test2)){
            addMoveSquare2(x,y, path);
            getSquares2(x+1,y,movesused+1,path+"r");
            getSquares2(x,y+1,movesused+1,path+"d");
            getSquares2(x,y-1,movesused+1,path+"u");
            getSquares2(x-1,y,movesused+1,path+"l");
        }
    }
    public void addMoveSquare2(int x, int y, String path){
        if(x >= 0 && y>=0 && x < Map.x && y < Map.y && (actPath[x][y] == null || actPath[x][y].length() > path.length())){
            if(squareListener[x][y] == null){
                actPath[x][y] = new String();
                actPath[x][y] = path;
                JLabel square = new JLabel();
                square.setBounds(x*16,y*16,16,16);
                square.setIcon(moveSquare);
                squareListener[x][y] = new SquareListener(x,y,path);
                square.addMouseListener(squareListener[x][y]);
                Map.cases.add(square);
            }
            else{
                squareListener[x][y].path = path;
            }
        }
    }

SquareListener 是一个简单的 MouseListener,它打印正方形的位置和路径。 Map.x, Map.y 是地图大小。 以起点调用getSquares2,绘制每一个距离为6步的方格,并将每一个值为“11”的情况视为障碍。

你能帮我找出我做错了什么吗?

这是结果的屏幕截图: http://img808.imageshack.us/img808/96/screen.gif 红色方块是可能的目标。只有当玩家点击一个方格时才会定义真正的方格(MouseListener 是 SquareListener,它应该知道要走的路径)。房屋是价值为“11”的箱子,即障碍物。

【问题讨论】:

  • 如果这是课堂作业,习惯上加上“homework”标签。
  • 将源码发布到整个程序中。
  • 这不是课堂作业。探路者只是程序的一部分。我需要添加什么?

标签: java recursion path-finding


【解决方案1】:

您的算法看起来几乎正确。几乎,因为在找到节点的第二条路径时忘记分配actPath[x][y],导致使用actPath[x][y] 的长度检查不正确。你应该这样做:

        else{
            actPath[x][y] = path;             
            squareListener[x][y].path = path;
        }

您的算法还具有令人讨厌的时间复杂度,因为它将迭代所有长度为 6 的路径(全部 4^6 = 4096 个)而不是最短的路径(6*6 + 5*5 = 61)

为了获得灵感,我建议查看Dijkstra's algorithm(A* 的前身),当路径长度为小整数时,它设法只访问最短路径并以 O(可达节点数)结束,就像这里的情况一样.

【讨论】:

  • 非常感谢!这确实是问题所在。我会努力让它变得更好。
【解决方案2】:

您可以在我的答案中查看here A-Star 的示例代码,这不是直接的答案,但代码是可读的,它为您指明了一本处理(以及许多其他事情)寻路的好书。我从来没有抽出时间来评论代码......

不知道你的意思,在丹尼尔的评论中,“谢谢你的链接,但是,我没有一个目标,而是一些动作,这使得很多可能的目标。”

【讨论】:

    【解决方案3】:

    您可能对A* search algorithm 上的这个tutorial 感兴趣。

    【讨论】:

    • 感谢您的链接,但是,我没有一个目标,而是有很多动作,这使得很多可能的目标。这不是使“F = G + H”的“H”无法使用吗?
    • @Cheshire:我不确定我是否遵循,但如果你有几个可能的目标并且你只想找到最接近的一个,听起来你可能想要 Dijkstra 算法(基本上,其中 H= 0)。该教程的底部有一些信息,或者您可能会发现 Wikipedia 页面很有用:en.wikipedia.org/wiki/Dijkstras_algorithm
    • 我添加了一张图片以使其更易于理解。
    • 链接失效了,有备份吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多