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(我)); } 返回结果; } }