A*寻路算法给出了奇怪的路径(文本地图-无GUI)

4
我正在尝试解决 A* 寻路算法的问题。我有三个类:MenuGridNode
如果你运行我的程序,你会看到它打印出一个不寻常的螺旋形路径。我认为这种意外行为与以下函数有关:printAStarPath(int startx, int starty, int endx, int endy)
在我看来,我认为问题与不正确设置父节点有关。我相信 NodeMenu 工作正常。
输入:
菜单函数基本上管理用户输入。用户可以添加墙壁、起始位置和结束位置以及网格大小。我还在菜单中包含了一些测试(这样你就不必每次测试时都要再次输入)。printAStarPath(...) 函数接受起始 x,y 位置和结束 x,y 位置。
输出:
我希望它打印出一个像这样的网格:
[ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][X][ ][ ][ ]
[ ][S][ ][X][ ][E][ ]
[ ][ ][*][X][*][ ][ ]
[ ][ ][ ][*][ ][ ][ ]

很抱歉,我遇到了这种疯狂的问题:
[ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][X][ ][ ][*]
[ ][S][ ][X][ ][E][*]
[ ][ ][*][X][ ][ ][*]
[ ][ ][ ][*][*][*][ ]

以下是使用不同输入时的另一个示例:

[E][ ][ ][ ][ ]
[ ][*][ ][ ][*]
[ ][ ][X][ ][*]
[ ][ ][ ][ ][*]
[ ][*][ ][*][S]

我的一些网格看起来像是向右下方的箭头。有些则像是向右下方走然后螺旋向左上方。


概要:

我正在使用A*路径查找算法,并通过曼哈顿方法计算启发式(或H成本)。我使用递归来获取确切的G成本,并从结束位置回溯到起始位置。

这是我遵循的文章。


这是代码:

菜单:

package pathFinding;

import java.util.*;

public class Menu {
    
    private Grid board;
    
    public Menu(){
        board = new Grid(0, 0);
    }//end constructor
    
    static public void main (String[] args){
        
        Menu pft = new Menu();
        
        pft.boardMenu();
        
        System.out.print("process terminated.");
        
    }//end main
    
    public void boardMenu(){
        // very user error prone !
        boolean kg = true;
        Scanner in = new Scanner(System.in);
        int input;
        
        while(kg){
            input = -1;
            System.out.print("\n\n\n\n");
            System.out.print(">>> Hi there,"
                         + "\n(0) quit"
                         + "\n(1) test 1"
                         + "\n(2) test 2"
                         + "\n(3) new board"
                         + "\n>>> ");
            input = in.nextInt();
            
            if (input == 3){
                this.initUserData();
            } else if (input == 0){
                kg = false;
            } else if (input == 1){
                board.setSize(7, 5);
                board.setCollidable(3, 1);
                board.setCollidable(3, 2);
                board.setCollidable(3, 3);
                board.printAStarPath(1, 2, 5, 2);
            } else if (input == 2){
                board.setSize(25, 25);
                board.setCollidable(5, 4);
                board.setCollidable(4, 5);
                board.setCollidable(3, 3);
                board.printAStarPath(15, 15, 4, 4);
            }
        } // end while
    } // end boardMenu
    
    public void initUserData(){
        boolean kgTmp = true;
        int xTmp, yTmp, iTmp, jTmp = 0;
        
        // initiate input device
        Scanner in = new Scanner(System.in);
        
        // 0: determine board size
        System.out.print("\nBoard width: ");
        xTmp = in.nextInt();
        System.out.print("\nBoard height: ");
        yTmp = in.nextInt();
        board.setSize(xTmp, yTmp);
        
        // 1: determine obstruction locations
        kgTmp = true;
        while(kgTmp){
            System.out.print("\nObstruction x Loc: ");
            xTmp = in.nextInt();
            System.out.print("\nObstruction y Loc: ");
            yTmp = in.nextInt();
            board.setCollidable(xTmp, yTmp);
            
            System.out.print("\nMore Obstructions?(0=no;1=yes): ");
            if(in.nextInt() == 0)
                kgTmp = false;
        } // end while
        
        // 2: determine start location
        System.out.print("\nStart x Loc: ");
        xTmp = in.nextInt();
        System.out.print("\nStart y Loc: ");
        yTmp = in.nextInt();
        
        // 3: determine end location
        System.out.print("\nEnd x Loc: ");
        iTmp = in.nextInt();
        System.out.print("\nEnd y Loc: ");
        jTmp = in.nextInt();
        
        System.out.println("\nredy for astar");
        // 4: determine and print A* path
        board.printAStarPath(xTmp, yTmp, iTmp, jTmp);
        System.out.println("\nastar shud be done?");
        
    } // end initBoardData

} // end class def

Grid:

package pathFinding;

import java.util.*;

public class Grid {
    
    private List<List<Node>> grid;
    List<List<Integer>> path;
    private int width;
    private int height;
    
    //------------------------------------------------------------------------
    // Name: Constructor
    // Desc: Takes in a width & height. Initializes stuff.
    //------------------------------------------------------------------------
    public Grid(int width, int height){
        
        grid = new ArrayList<List<Node>>();
        path = new ArrayList<List<Integer>>();
        this.width = width;
        this.height = height;
        initGrid(width, height);
        
    } // end constructor
    
    //------------------------------------------------------------------------
    // Name: initGrid
    // Desc: initializes the grid with data
    //------------------------------------------------------------------------
    public void initGrid(int w, int h){
        
        // add columns
        for (int i=0;i<w;i++)
            grid.add(new ArrayList<Node>());
        
        // fill grid with nodes
        for (int i=0;i<w;i++)
            for (int j=0;j<h;j++)
                grid.get(i).add(new Node(i, j));
        
    } // end initGrid
    
    //------------------------------------------------------------------------
    // Name: setSize
    // Desc: Sets the size of the grid
    //------------------------------------------------------------------------
    public void setSize(int w, int h){
        this.width = w;
        this.height = h;
        
        // update the nodes
        clearAll();
        initGrid(width, height);
        
    } // end setSize
    
    //------------------------------------------------------------------------
    // Name: clearAll
    // Desc: Clears any data in grid and path
    //------------------------------------------------------------------------
    public void clearAll(){
        // removes all rows/columns/nodes
        grid.clear();
        path.clear();
    } // end clearAll
    
    //------------------------------------------------------------------------
    // Name: printGrid
    // Desc: Prints the whole grid
    //------------------------------------------------------------------------
    public void printGrid(){
        // prints every node's value
        
        // loop thru columns
        for (int j=0;j<height;j++){
            // thru row
            for (int i=0;i<width;i++)
                grid.get(i).get(j).printText();
            System.out.println();
        } // end j loop
    } // end printGrid
    
    //------------------------------------------------------------------------
    // Name: setCollidable
    // Desc: Sets a node at x,y to collidable
    //------------------------------------------------------------------------
    public void setCollidable(int x, int y){
        
        // makes a node at x,y collidable
        grid.get(x).get(y).setCollidable(true);
        grid.get(x).get(y).setText("[X]");
        
    } // end setCollidable
    
    //------------------------------------------------------------------------
    // Name: printAStarPath
    // Desc: Finds and prints the path from start to end
    // Errr: This function only almost works :(   ... oh well i tried
    //------------------------------------------------------------------------
    public void printAStarPath(int startx, int starty, int endx, int endy){
        
        //========================================================
        // PSEUDO CODE BRO.
        //========================================================
        // 1: Declarations
        //    PART ONE
        // 2: Initialize:
        //    1: Drop current node from openList
        //       Add current node to closedList
        //    2: Set current node as parent for each neighbor
        //       Add neighbors to openList
        //
        //    PART TWO
        // 3: Loop: (thru openList)
        //
        //       (openList should contain neighbors of closedList nodes here)
        //
        //    EXAMPLE:
        //
        //    n n n n n
        //    n n n n n>
        //    n S * * n-> E      (the closest star is the current node)
        //    n n n n n>
        //    n n n n n
        //
        //    1: Set neighbor w/ lowest F-cost from the openList as current node
        //    2: Add this new node to the closedList
        //       Remove from openList
        //    3: Loop (for each neighbor):
        //       1: Add openlist'less neighbors to openList
        //          Set current node as parent for neighbor node
        //       2: If neighbor is already on the openList:
        //          1: Get G-cost of neighbor IF: neighbor's parent is current node's parent (default)
        //                                    IF: neighbor's parent is current node
        //          2: If the 2nd G-cost is less:
        //             1: set neighbor's parent to current node
        //             2: recalculate F and G costs (possibly you don't need this)
        //    4: Stop: IF: end node is in closedList or,
        //             IF: end node is not in closedList and openList is empty
        // 4: Save/Return Path
        // 5: Print Results: (if you wanna print)
        //    1: Fill grid with proper symbols
        //    2: Print grid
        
        
        
        //===========//
        //     1     //
        //===========//
        List<List<Integer>> closedList = new ArrayList<List<Integer>>();
        List<List<Integer>> openList   = new ArrayList<List<Integer>>();
        int x                          = startx;
        int y                          = starty;
        int gOrig                      = 0;
        int gThru                      = 0;
        boolean condition              = false;
        
        //===========//
        //     2     //
        //===========//
        if (closedList.contains(Arrays.asList(x, y)) == false)
            closedList.add(Arrays.asList(x, y));
        for (int i=x-1;i<x+2;i++){
            for (int j=y-1;j<y+2;j++){
                if (i>=0 && i<this.width){
                    if (j>=0 && j<this.height){
                        if (closedList.contains(Arrays.asList(i, j)) == false){
                            if (grid.get(i).get(j).getCollidable() == false){
                                //-----------------------------------------------------

                                // setting parent
                                grid.get(i).get(j).setParent( grid.get(x).get(y) );
                                // adding to openList
                                openList.add(Arrays.asList(i, j));

                                //-----------------------------------------------------
                            }//end if (check collidable)
                        }//end if (in closedList?)
                    }//end if (check height)
                }//end if (check width)
            }//end j loop
        }//end i loop
        
        
        //===========//
        //     3     //
        //===========//
        while(condition == false){
            
            
            //===========//
            //    3.1    //
            //===========//
            // selecting lowest F-cost node
            x = getLowestFCostNodePos(openList, endx, endy)[0];
            y = getLowestFCostNodePos(openList, endx, endy)[1];
            
            //===========//
            //    3.2    //
            //===========//
            closedList.add(Arrays.asList(x, y));
            openList.remove(Arrays.asList(x, y));
            
            //===========//
            //    3.3    //
            //===========//
            for (int i=x-1;i<x+2;i++){
                for (int j=y-1;j<y+2;j++){
                    if (i>=0 && i<this.width){
                        if (j>=0 && j<this.height){
                            if (closedList.contains(Arrays.asList(i, j)) == false){
                                if (grid.get(i).get(j).getCollidable() == false){
                                    //-----------------------------------------------------

                                    if (openList.contains(Arrays.asList(i, j)) == false){
                                        // setting parent
                                        grid.get(i).get(j).setParent( grid.get(x).get(y) );
                                        // adding to openList
                                        openList.add(Arrays.asList(i, j));
                                    }//end if (in openList?)
                                    
                                    else{
                                        // getting G-costs
                                        gOrig = grid.get(i).get(j).getG();
                                        grid.get(i).get(j).setParent(grid.get(x).get(y));
                                        gThru = grid.get(i).get(j).getG();
                                        
                                        // comparing G-costs
                                        if (gOrig < gThru){
                                            // revert parent back the way it was
                                            grid.get(i).get(j).setParent(grid.get(x).get(y).getParent());
                                        }//end if (G-costs)
                                        
                                        // adding to openList
                                        openList.add(Arrays.asList(i, j));
                                    }//end else (in openList?)

                                    //-----------------------------------------------------
                                }//end if (check collidable)
                            }//end if (in closedList?)
                        }//end if (check height)
                    }//end if (check width)
                }//end j loop
            }//end i loop
            
            
            //===========//
            //    3.5    //
            //===========//
            if (openList.size() == 0){
                condition = true;
                System.out.print("\nNo Path.\n");
            } else if (closedList.contains(Arrays.asList(endx, endy)) == true){
                condition = true;
                System.out.print("\nPath Found.\n");
            }
            
            
        }//end while loop (condition)
        
        
        //===========//
        //     4     //
        //===========//
        if (openList.size() > 0)
            getNodePath(grid.get(endx).get(endy));
        
        
        //===========//
        //    5.1    //
        //===========//
        if (openList.size() > 0)
            for (int i=0; i<path.size(); i++){
                // setting symbols
                grid.get(path.get(i).get(0)).get(path.get(i).get(1)).setText("[*]");
            }
        // setting start/end
        grid.get(startx).get(starty).setText("[S]");
        grid.get(endx).get(endy).setText("[E]");
        
        
        //===========//
        //    5.2    //
        //===========//
        printGrid();
        
        
    } // end printAStarPath


    //------------------------------------------------------------------
    //  Name: getNodePath
    //  Desc: returns coordinates of path (in order) from start to end
    //------------------------------------------------------------------
    public void getNodePath(Node node){
        
        // redo this function with the parent of node
        if (node.getParent() != null){
            // add a coordinate to path list
            this.path.add(0, Arrays.asList(node.getX(), node.getY()));
            // recur
            getNodePath(node.getParent());
        }//end if (recursive)
        
    } // end getNodePath
    
    
    //------------------------------------------------------------------
    //  Name: getLowestFCostNodePos
    //  Desc: returns coordinates of node with lowest F-cost in openList
    //------------------------------------------------------------------
    public int[] getLowestFCostNodePos(List<List<Integer>> openList, int endx, int endy){
        // Declarations
        int xTmp = 0;
        int yTmp = 0;
        int fMin = 1000000;
        int[] cords = new int[2];
        
        // look for lowest F-cost node
        for (int i=0;i<openList.size();i++){
            // setting possible position
            xTmp = openList.get(i).get(0);
            yTmp = openList.get(i).get(1);
            
            // compare F-values
            if (fMin > grid.get(xTmp).get(yTmp).getF(endx, endy)){
                // set temporary F-cost
                fMin = grid.get(xTmp).get(yTmp).getF(endx, endy);
            }//end if (compare F)
        }//end i loop
        
        // just in case
        if (openList.size() > 0){
            cords[0] = xTmp;
            cords[1] = yTmp;
            return cords;
        } else{
            System.out.print("openList is empty!");
            return null;
        }
        
    } // end getLowestFCostNodePos

} // end class def

Node:

package pathFinding;

public class Node {
    
    private String text;
    private int x;
    private int y;
    private boolean collidable;
    private Node parent;
    
    public Node(int x, int y){
        
        text = "[ ]";
        this.x = x;
        this.y = y;
        collidable = false;
        parent = null;
        
    } // end constructor
    
    public void setText(String text){
        this.text = text;
    } // end setText
    
    public int getX(){
        return this.x;
    } // end getX

    public int getY(){
        return this.y;
    } // end getY
    
    public void setCollidable(boolean arg0){
        collidable = arg0;
    } // end setCollidable
    
    public boolean getCollidable(){
        return collidable;
    } // end getCollidable
    
    public void setParent(Node n){
        parent = n;
    } // end setParent
    
    public Node getParent(){
        // for parent location: return new int[] {parent.getX(), parent.getY()};
        return parent;
    } // end getParent
    
    public void printText(){
        System.out.print(this.text);
    } // end printText
    
    public int getF(int endx, int endy){
        return this.getG() + this.getH(endx, endy);
    } // end getF
    
    public int getG(){
        // calculate exact distance from start
        if (parent != null){
            if (parent.getX()-this.x == 0 || parent.getY()-this.y == 0)
                return parent.getG() + 10;
            else
                return parent.getG() + 14;
        }//end if
        return 0;
    } // end getG
    
    public int getH(int endx, int endy){
        // calculate estimated distance to end (Manhattan distance)
        return (Math.abs(this.x-endx) + Math.abs(this.y-endy))*10;
    } // end getH

} // end class def

编辑:

我一段时间后回到了这段代码,测试了一个新的图表,但是很遗憾,它给了我这个:

[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][X][ ][ ][ ][ ]
[ ][ ][X][X][X][X][ ][*][ ][ ]
[ ][ ][*][*][E][X][ ][ ][*][ ]
[ ][*][X][X][X][X][ ][ ][ ][S]
[ ][ ][*][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][*][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][*][ ][*][ ][ ][ ]
[ ][ ][ ][ ][ ][*][ ][ ][ ][ ]

有人能解释一下为什么会发生这种情况吗?

你尝试过使用调试器吗?顺便说一句,仅仅粘贴一堵代码墙,甚至不说明输入是什么,期望输出是什么以及实际输出是什么,这并不能激励人们帮助你。 - Programmer Person
通常我会同意,但他至少大致描述了他尝试解决问题的方法。我认为代码墙来自于他试图不遗漏任何细节。但是通常情况下,最好提供一个出现问题的小代码片段。 - Neilos
2
为了让A*算法正常工作,启发式函数(getH)不能够高估从A到B的最短路径。由于你允许斜向移动比水平方向+对角线方向移动更短,所以你不能将其作为H的估算值。我不知道这是否能解决你的问题,但至少可以解决其中一个问题。 - Krycke
@Neilos:他有点儿想法,知道问题出在哪里,很好。但我们还有什么线索?标题? - Programmer Person
2个回答

4

好的,我已经查看了您的代码,并在这里得到其他人的评论帮助下成功使其工作。我只发布更改后的方法:

Grid.getLowestFCostNodePos没有跟踪具有最低F值的节点的X和Y值:

public int[] getLowestFCostNodePos(List<List<Integer>> openList, int endx, int endy){
    // Declarations
    int fMin = 1000000;
    int[] cords = new int[2];
    int minX = -1;
    int minY = -1;

    // look for lowest F-cost node
    for (int i=0;i<openList.size();i++){
        // setting possible position
        int xTmp = openList.get(i).get(0);
        int yTmp = openList.get(i).get(1);

        int fCandidate = grid.get(xTmp).get(yTmp).getF(endx, endy);
        // compare F-values
        if (fMin > fCandidate) {
            // set temporary F-cost
            fMin = fCandidate;
            minX = xTmp;
            minY = yTmp;
        }//end if (compare F)
    }//end i loop

    // just in case
    if (openList.size() > 0){
        cords[0] = minX;
        cords[1] = minY;
        return cords;
    } else{
        System.out.print("openList is empty!");
        return null;
    }

} // end getLowestFCostNodePos

Node.getG()Node.getH()使用的计量单位不同(H认为一步值得1个单位,而G认为一步值得10个单位,对于N/S/E/W步骤,对于对角线步骤的14个单位),并且H不考虑对角线步骤。我已对此进行了规范化处理,使得每一步始终花费1个单位:

public int getG(){
    // calculate exact distance from start
    if (parent != null){
        return parent.getG() + 1;
    }//end if
    return 0;
} // end getG

public int getH(int endx, int endy){
    // calculate estimated distance to end
    // Since we can walk diagonally we can cover the smallest of
    // dx and dy while covering the longest. The distance is therefore
    // the largest of the two
    return Math.max(Math.abs(this.x - endx), Math.abs(this.y - endy));
} // end getH

测试板1:

[ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][X][ ][ ][ ]
[ ][S][ ][X][ ][E][ ]
[ ][ ][*][X][*][ ][ ]
[ ][ ][ ][*][ ][ ][ ]

测试板2:

[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][X][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][E][X][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][X][*][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][*][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][*][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][*][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][*][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][*][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][*][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][*][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][*][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][*][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][S][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]

自定义板:

[S][X][ ][ ][ ]
[*][X][ ][*][ ]
[*][X][*][X][*]
[*][X][*][X][*]
[ ][*][ ][X][E]

话虽如此,您应该考虑实现一个 Point 类,而不是在任何地方使用 ArrayList,并使用局部变量和辅助方法,因为您的代码非常冗长且难以阅读。

像这样的行让我头疼:

grid.get(path.get(i).get(0)).get(path.get(i).get(1)).setText("[*]");

ArrayList<Integer>更改为自定义的Point类并使用两个本地变量可以大大提高可读性:

Point point = path.get(i);
List<Node> row = grid.get(point.getX());
row.get(point.getY()).setText("[*]");

如果您要向Grid添加一个实用方法,以获取来自Point的特定Node,则可以将其简化为:
getNode(path.get(i)).setText("[*]");

这种方法在很多地方都可以用来提高可读性。


太棒了,它起作用了!但是,归一化是什么意思?曼哈顿启发式有什么问题吗? - Ibrahim
1
由于你的算法允许对角线步骤,因此我们可以通过沿对角线前进从(0,0)到(4,4)走4步,而这两点之间的曼哈顿距离为8。 - Raniz

1
我没有读完你的代码,但是在getLowestFCostNodePos函数中至少存在一个错误。请注意,你返回的坐标不是具有最小FCost的坐标,而是openList中最后一个节点的坐标,因为你无条件地更新了xTmpyTmp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接