/// <summary> /// 获得保证最小消耗的路径(需要访问所有节点)BFS /// 时间复杂度:O(nlgn) /// 空间复杂度 O(n) /// </summary> /// <param name="start"></param> /// <param name="end"></param> /// <param name="nodesMap"></param> /// <returns></returns> public static Queue <Node> FindWay( Node start, Node end, Dictionary <Node, int> nodesMap ) { //Init FindPathAlgorithm.Init(nodesMap); //First Node canGetMinNodelist.Add(start); int curcount = 1; CostDict[start] = 0; RoadDict[start].Enqueue(start); visit[start] = true; curcount++; //Find while (curcount < NodeCount && canGetMinNodelist.Count > 0) { //查找访问过节点中距离终点最近的点 Node cur = (Node)GetMinNodeFromArr(canGetMinNodelist, end, x => H(x, end)); //查找cur所能到达的节点列表 List <Node> arr = GetNearbyNode(cur, false); //遍历列表里的所有的节点 for (int i = 0; i < arr.Count; i++) { Node n = arr[i]; //设置为已访问 if (!visit[n]) { canGetMinNodelist.Add(n); visit[n] = true; curcount++; } //如果新的路径更短,更新路径 int newcost = CostDict[cur] + NodesMap[n]; if (CostDict[n] > newcost) { CostDict[n] = newcost; RoadDict[n] = new Queue <Node>(RoadDict[cur]); RoadDict[n].Enqueue(n); } } canGetMinNodelist.Remove(cur); } return(RoadDict[end]); }
/// <summary> /// 以距离为导向的寻路 /// </summary> /// <param name="start"></param> /// <param name="end"></param> /// <param name="nodesMap"></param> /// <returns></returns> public static Queue <Node> FindWayGreedy( Node start, Node end, Dictionary <Node, int> nodesMap ) { //Init FindPathAlgorithm.Init(nodesMap); //First Node CostDict[start] = 0; RoadDict[start].Enqueue(start); Func <Node, int> GetMin = node => (int)(Math.Pow(node.x - end.x, 2) + Math.Pow(node.z - end.z, 2)); canGetMinNodelist.Add(start); Node?curnode = null; Node cur = start; //Find while (cur != end) { //查找访问过节点中距离终点最近的节点 curnode = GetMinNodeFromArr(canGetMinNodelist, end, GetMin); //无法到达终点 if (null == curnode) { break; } //查找curnode下一个节点中距离终点最近的点 cur = (Node)curnode; Node?minnode = GetMinNode(cur, end, GetMin); if (null == minnode) { //当前节点无法到达终点 canGetMinNodelist.Remove(cur); continue; } else { Node _min = (Node)minnode; //标记为已访问 visit[_min] = true; canGetMinNodelist.Add(_min); //更新路径 CostDict[_min] = CostDict[cur] + NodesMap[_min]; RoadDict[_min].Clear(); foreach (var e in RoadDict[cur]) { RoadDict[_min].Enqueue(e); } RoadDict[_min].Enqueue(_min); } } return(RoadDict[end]); }