一个高效的a *寻路算法(八方向)

    xiaoxiao2021-03-27  31

    http://blog.csdn.net/onafioo/article/details/41089579

    这种写法比较垃圾,表现在每次搜索一个点要遍历整个地图那么大的数组,如果地图为256 * 256,每次搜索都要执行65535次,如果遍历多个点就是n * 65535,速度上实在是太垃圾了

    简单说下思路,以后补充算法

    优化重点在表在开放和关闭表的遍历上,这两个地方优化后,斯达会大量提速

    亲密只用来查询所以可以用哈希这样就避免了遍历

    打开首先用来查询是否有相同的点如果有会比较替换F值,其次用来遍历查询最小点,如果用优先级队列加哈希可以减少2次遍历,但是相同点替换F值和父节点就没办法了,只能遍历一次(但一般找到该找的点就可以休息,不需要完整遍历)

    如果用Javac#,由于有垃圾回收机制,为了避免产生过多垃圾降低垃圾回收压力,可以用空闲对象池来避免频繁创建节点,控制内存泄露

     

     

     

    原作者是http://www.codefans.net的贾罗德

    之所以说这个a *算法高效,是因为它的开放列表和close-list使用的完全是静态数组,这样就极大地降低了入栈出栈的负担。这个代码非常值得推荐。 用法很简单: 结果route_pt[]=零; / / result_pt是一个简单类,它只有两个成员变量:int x和int y。 / /参数说明:地图是一个二维数组,具体见程序注释 AStarRoute2 asr = new AStarRoute2(地图,start_x,start_y、end_x end_y); 尝试{      结果= asr.getResult(); }捕捉(例外的前女友){ } 如果结果! =零那么寻路就成功了。 注意:最后获得的路径,是从终点指向起点的。您可以把两组参数倒过来传,以获得正常方向的返回值。 本人对贾罗德的代码略作修改,主要是用循环取代了递归,避免栈溢出。 这是本人修改后的八方向寻路算法。如下: 进口java.util.ArrayList; 公开课AStarRoute2 {     私人int[][]地图;/ /地图矩阵,0表示能通过,1表示不能通过     私人int map_w;  / /地图宽度     私人int map_h;  / /地图高度     私人int start_x;/ /起点坐标X     私人int start_y;/ /起点坐标Y     私人int goal_x;/ /终点坐标X     私人int goal_y;/ /终点坐标Y     私人布尔closeList[][];          / /关闭列表     公共int openList[][][];            / /打开列表     私人int openListLength;     私有静态最终int存在= 1;     私有静态最终int NOT_EXIST = 0;     私有静态最终int ISEXIST = 0;     私有静态最终int费用= 1;  / /自身的代价     私有静态最终int距离= 2;  / /距离的代价     私有静态最终int成本= 3;      / /消耗的总代价     私有静态最终int FATHER_DIR = 4;/ /父节点的方向     公共静态最终int DIR_NULL = 0;     公共静态最终int DIR_DOWN = 1;  / /方向:下     公共静态最终int DIR_UP = 2;    / /方向:上     公共静态最终int DIR_LEFT = 3;  / /方向:左     公共静态最终int DIR_RIGHT = 4;  / /方向右     公共静态最终int DIR_UP_LEFT = 5;     公共静态最终int DIR_UP_RIGHT = 6;     公共静态最终int DIR_DOWN_LEFT = 7;     公共静态最终int DIR_DOWN_RIGHT = 8;     私人int astar_counter;              / /算法嵌套深度     私人布尔isFound;                / /是否找到路径     公共AStarRoute2(int[][]mx,int sx,int sy,int gx,int gy){         start_x = sx;         start_y = sy;         goal_x= gx;         goal_y= gy;         地图  = mx;        map_w= mx.length;         map_h= mx[0]. length;         astar_counter = 5000;         initCloseList();         initOpenList(goal_x goal_y);     }     / /得到地图上这一点的消耗值     私人int getMapExpense(int x,int y,int dir)     {         如果(dir < 5){             返回10;         其他} {             返回14;         }     }     / /得到距离的消耗值     私人int getDistance(int x,int y,int,int)等等)     {         返回10 *(数学。 abs(x - ex)+数学。 abs(y -迪士尼));     }     / /得到给定坐标格子此时的总消耗值     私人int getCost(int x,int y)     {         返回openList[x][y][费用];     }     / /开始寻路     公共空间searchPath()     {         addOpenList(start_x start_y);         斯达(start_x start_y);     }     / /寻路     私人空间斯达(int x,int y)     {         / /控制算法深度         (int t = 0;t < astar_counter;t + +){             如果(((x = = goal_x)& &(y = = goal_y))){                 isFound = true;                 返回;             }             else if((openListLength = = 0)){                 isFound = false;                 返回;             }             removeOpenList(x,y);             addCloseList(x,y);             / /该点周围能够行走的点             addNewOpenList(x,y,x,y + 1,DIR_UP);             addNewOpenList(x,y,x,y - 1,DIR_DOWN);             addNewOpenList(x,y,x - 1,y,DIR_RIGHT);             addNewOpenList(x,y,x + 1,y,DIR_LEFT);             addNewOpenList(x,y,x + 1,y + 1,DIR_UP_LEFT);             addNewOpenList(x,y,x - 1,y + 1,DIR_UP_RIGHT);             addNewOpenList(x,y,x + 1,y - 1,DIR_DOWN_LEFT);             addNewOpenList(x,y,x - 1,y - 1,DIR_DOWN_RIGHT);             / /找到估值最小的点,进行下一轮算法             int成本= 0 x7fffffff;             for(int i = 0;我< map_w;+ +){                 for(int j = 0;< map_h;j + +){                     如果(openList[我][j][ISEXIST]= =存在){                         如果(成本> getCost(i,j)){                             成本= getCost(i,j);                             x =我;                             y = j;                         }                     }                 }             }         }         / /算法超深         isFound = false;         返回;     }     / /添加一个新的节点     私人空间addNewOpenList(int x,int y,int newX,int newY,int dir)     {         如果(isCanPass(newX newY)){             如果(openList[newX][newY][ISEXIST]= =存在){                 如果(openList[x][y][费用]+ getMapExpense(newX、newY dir)<                     openList[newX][newY][费用]){                     setFatherDir(newX newY dir);                     setCost(newX newY,x,y,dir);                 }             其他} {                 addOpenList(newX newY);                 setFatherDir(newX newY dir);                 setCost(newX newY,x,y,dir);             }         }     }     / /设置消耗值     私人空间setCost(int x,int y,int,int,int dir)     {         openList[x][y][费用]= openList[例][是][费用]  + getMapExpense(x,y,dir);         openList[x][y][距离]= getDistance(x,y,交货哦,是吧);         openList[x][y][费用]= openList[x][y][费用]  + openList[x][y](距离);     }     / /设置父节点方向     私人空间setFatherDir(int x,int y,int dir)     {         openList[x][y][FATHER_DIR]= dir;     }     / /判断一个点是否可以通过     私人布尔isCanPass(int x,int y)     {         / /超出边界         如果(x < 0 | | x > = map_w | | y < 0 | | y > = map_h){             返回错误;         }         / /地图不通         如果(map[x][y]! = 0){             返回错误;         }         / /在关闭列表中         如果(isInCloseList(x,y)){             返回错误;         }         返回true;     }     / /移除打开列表的一个元素     私人空间removeOpenList(int x,int y)     {         如果(openList[x][y][ISEXIST]= =存在){             openList[x][y][ISEXIST]= NOT_EXIST;             openListLength——;         }     }     / /判断一点是否在关闭列表中     私人布尔isInCloseList(int x,int y)     {         返回closeList[x][y];     }     / /添加关闭列表     私人空间addCloseList(int x,int y)     {         closeList[x][y]= true;     }     / /添加打开列表     私人空间addOpenList(int x,int y)     {         如果(openList[x][y][ISEXIST]= = NOT_EXIST){             openList[x][y][ISEXIST]=存在;             openListLength + +;         }     }     / /初始化关闭列表     私人空间initCloseList()     {         closeList = new布尔[map_w][map_h];         for(int i = 0;我< map_w;+ +){             for(int j = 0;< map_h;j + +){                 closeList[我][j]= false;             }         }     }     / /初始化打开列表     私人空间initOpenList(int,int)等等)     {         openList= new int[map_w][map_h][5];         for(int i = 0;我< map_w;+ +){             for(int j = 0;< map_h;j + +){                 openList[我][j][ISEXIST]= NOT_EXIST;                 openList[我][j][费用]= getMapExpense(i,j,DIR_NULL);                 openList[我][j][距离]= getDistance(i,j,交货哦,是吧);                 openList[我][j][费用]= openList[我][j][费用]  + openList[我][j](距离);                 openList[我][j][FATHER_DIR]= DIR_NULL;             }         }         openListLength = 0;     }     / /获得寻路结果     公共route_pt[]getResult(){         route_pt[]的结果;         ArrayList < route_pt >路线;         searchPath();         如果(! isFound){             返回null;         }         路线= new ArrayList < route_pt >();         / / openList是从目标点向起始点倒推的。         int第九= goal_x;         int iY = goal_y;         而(第九! = start_x | | iY ! = start_y)){             路线。 添加(新route_pt(第九,iY));             开关(openList[iX][iY][FATHER_DIR]){             案例DIR_DOWN:        iY + +;          打破;             案例DIR_UP:          iY——;          打破;             案例DIR_LEFT:        第九,;          打破;             案例DIR_RIGHT:      第九+ +;          打破;             案例DIR_UP_LEFT:    第九,;iY——;  打破;             案例DIR_UP_RIGHT:    第九+ +;iY——;  打破;             案例DIR_DOWN_LEFT:  第九,;iY + +;  打破;             案例DIR_DOWN_RIGHT:  第九+ +;iY + +;  打破;             }         }         int大小= route.size();         结果= new route_pt(大小);         for(int i = 0;我+ +){ <大小;             结果新route_pt[我]=((route_pt)route.get(我));         }         返回结果;     } }

    转载请注明原文地址: https://ju.6miu.com/read-664394.html

    最新回复(0)