赞
踩
A星寻路算法简介
A星寻路算法(A* Search Algorithm)是一种启发式搜索算法,它在图形平面上进行搜索,寻找从起始点到终点的最短路径。A星算法结合了广度优先搜索(BFS)和最佳优先搜索(Best-First Search)的特点,通过使用启发式函数评估节点的重要性,优先选择最有希望达到目标节点的节点进行扩展,从而有效地缩小搜索范围。
A星寻路算法的核心概念
A星寻路算法的步骤
代码实现
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; //节点 public class AstarNode:IComparable<AstarNode> //继承接口实现重载排序方式 { public int x;//x坐标 public int y;//y坐标 public Vector2Int pos;//x,y坐标 public int G;//起点到该点的距离 public int H;//该点到终点的曼哈顿距离 public int F;//F = G + F public AstarNode() //无参构造函数 { } public AstarNode(Vector2Int pos) //有参构造函数 { this.pos = pos; this.x = pos.x; this.y = pos.y; } public int CompareTo(AstarNode other) //排序方式 { return this.F-other.F; //F小排在前 } } //A星 public class AStar { bool result =false; //单例模式 private static AStar instance; public static AStar Instance { get { if(instance==null) { instance = new AStar(); } return instance; } } //上右下左四个方向 private Vector2Int[] directions = new Vector2Int[]{new Vector2Int(1,0),new Vector2Int(0,1),new Vector2Int(-1,0),new Vector2Int(0,-1)};//上右下左 //开放表 private List<AstarNode> openList = new List<AstarNode>(); //关闭表,但这里没用到,用cameFrom代替了它的作用 //private HashSet<Vector2Int> closeList = new HashSet<Vector2Int>(); //路径字典,用来存储路径以及作为关闭表来判断该点是否已经走过 private Dictionary<Vector2Int,Vector2Int> cameFrom = new Dictionary<Vector2Int, Vector2Int>(); //记录最终路径,作为返回值 private List<Vector2Int> path = new List<Vector2Int>(); //寻路方法 public List<Vector2Int> FindPath(List<List<Transform>> map,Vector2Int startP,Vector2Int targetP)//地图,起点,终点 { Debug.Log("开始寻路"); //计算起点G,H,F,将起点加入开放表, AstarNode rNode = new AstarNode(startP); rNode.G = 0; rNode.H = Manhattan(rNode.pos,targetP); rNode.F = rNode.G+rNode.H; openList.Add(rNode); cameFrom[startP] = new Vector2Int(-1,-1); //记录路径,当前点坐标作为key,上一个点的坐标作为value,表示从上一个点坐标到达该点 //循环直到找到路径,或者开放表没有节点 while(openList.Count>0&&!result) { //开放表以F为标准排序,F小在前 openList.Sort(); //取出开放表中F最小的节点 AstarNode curNode = openList[0]; //取出的节点要从开放表中移除,加入到关闭表 openList.RemoveAt(0); //遍历这个点周围的四个方向 foreach(Vector2Int dir in directions) { Vector2Int newP = curNode.pos+dir; //判断边界,有没有超出地图范围 if(newP.x<0||newP.x>=map.Count||newP.y<0||newP.y>=map[0].Count) //边界点判断 { continue; } //判断是否在关闭表 if(cameFrom.ContainsValue(newP)) { continue; } //判断该点是否是障碍物 if(!map[newP.x][newP.y].gameObject.GetComponent<Tile>().CheckObstacle()) { continue; } //查看是否在开放表 AstarNode node = openList.FirstOrDefault(p => p.pos == newP);//linq查询openlist中是否有该点的节点 //不在开放表就计算G,H,F,加入开放表,边的代价默认为1 if(node==null) { //Debug.Log("添加"); AstarNode newNode = new AstarNode(); newNode.pos = newP; newNode.G = curNode.G+1; newNode.H = Manhattan(newNode.pos,targetP); newNode.F = newNode.G+newNode.H; cameFrom[newNode.pos] = curNode.pos; //记录路径 openList.Add(newNode); } else //在开放表,判断当前路径代价是否更小,是否要更新代价 { //如果当前路径代价更小,更新代价和路径 if(node.G > curNode.G+1) { node.G = curNode.G+1; node.F = node.G+node.H; cameFrom[node.pos] = curNode.pos; } } //如果当前点就是目标点,则停止寻路 if(curNode.pos == targetP) { result = true; break; } } } //如果找到路径,通过终点与cameFrom,从后往前找到整条路径。 if(result) { //通过栈把路径节点转成从起点到终点 Stack<Vector2Int> path_stack = new Stack<Vector2Int>(); Vector2Int pos = targetP; path_stack.Push(targetP); //将节点压入栈内 while(pos!=startP) { Vector2Int newP = cameFrom[pos]; pos = newP; path_stack.Push(pos); } //将栈内节点弹出 while(path_stack.Count>0) { pos = path_stack.Pop(); path.Add(pos); //Debug.Log(pos); } } else { Debug.Log("没找到"); } return path; } public int Manhattan(Vector2Int a,Vector2Int b) //获取两点曼哈顿距离 { return Mathf.Abs(a.x -b.x)+Mathf.Abs(a.y-b.y); } }
这段代码通过传递地图网格,地点和终点,实现了简单的A星寻路算法。首先构建一个新的Astar节点,设置为起点节点。起点的G为0,H采用曼哈顿距离,F = G + H。将起点节点加入到开放表。要取到开放表中F最小的节点,因为数据量较小,这里在每次从开放表取节点前都以F进行一次排序得到F最小节点(用优先队列会更好)。通过该节点访问其上右下左的四个点,并判断这些点是否能够加入开放表(坐标超出网格范围,节点在关闭表,节点是障碍点。都不能加入开放表)关闭表使用字典存储,在实现关闭表的同时还记录了节点之间的路径信息。最后判断坐标点是否在开放表,不在开放表的点构建节点并加入开放表,这里默认两点间的代价为1;在开放表中的则判断新的路径中代价是否更小,更小则更新代价和路径信息,否则不做处理。最后判断坐标点是否为目标坐标,如果是目标坐标即停止寻路。最后通过存储的路径信息找到完整路径。
A星寻路算法的优化技巧
A星寻路算法的应用
A星寻路算法广泛应用于游戏开发、机器人导航、路径规划等领域。以下是一些具体的应用场景:
总结
A星寻路算法是一种高效、实用的路径搜索算法,它结合了广度优先搜索和最佳优先搜索的特点,通过启发式函数评估节点的重要性,从而快速找到最短路径。通过合理的优化技巧,A星算法能够适多种应用场景,提高性能和准确性。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。