예제 #1
0
        /// <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]);
        }
예제 #2
0
        /// <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]);
        }