Exemple #1
0
    private void Search()
    {
        //创建一个索引的优先队列,按照从前到后从最小到最大来排序
        //注意iPQ包含的最大节点数是NodeCount()
        //这是因为没有界定啊在队列中会重复表示
        SortedList <float, int> iPQ = new SortedList <float, int>();

        //把源节点入队
        iPQ.Add(0, m_iSource);
        m_CostToThisNode.Add(m_iSource, 0);
        while (iPQ.Count > 0)
        {
            //从队列中得到最小开销的节点。别忘了返回的是节点的索引而不是节点本身
            //这个节点是在SPT中没有,但是又是距离源节点最近的节点
            int NextClosestNode = iPQ.First().Value;
            iPQ.RemoveAt(0);
            //把这条边从搜索边界移动到最短路径树上,m_searchFrontier[NextClosestNode]是和NextClosestNode节点最近的一条边
            if (m_searchFrontier.ContainsKey(NextClosestNode))
            {
                m_shortestPathTree.Add(NextClosestNode, m_searchFrontier[NextClosestNode]);
            }
            //如果找到目标节点,则退出
            if (NextClosestNode == m_iTarget)
            {
                return;
            }
            //现在进行边放松,遍历每一条连接下一个最近节点的边
            foreach (GraphEdge e in m_graph.GetRelatedEdges(NextClosestNode))
            {
                //到这条边指向的节点的总开销是到当前节点的开销加上这条连接边的开销
                float NewCost = m_CostToThisNode[NextClosestNode] + e.Cost;
                //如果这条边还没有在搜索边界上,记录它所指向的点的开销,
                //接着把边加到搜索边界,
                //把指向的节点加到优先队列
                if (!m_searchFrontier.ContainsKey(e.To))
                {
                    m_CostToThisNode.Add(e.To, NewCost);
                    iPQ.Add(NewCost, e.To);
                    m_searchFrontier.Add(e.To, e);
                }
                //如果已经加入到搜索边界,测试是否从当前节点到达边指向的节点的开销是否小于当前找到的最小开销
                //如果这条路径更短的话,我们将新的开销记入边指向的节点,更新优先队列以反映变化
                //把边加入最短路径
                else if (NewCost < m_CostToThisNode[e.To] && !m_shortestPathTree.ContainsKey(e.To))
                {
                    m_CostToThisNode[e.To] = NewCost;
                    foreach (KeyValuePair <float, int> pair in iPQ)
                    {
                        if (pair.Value == e.To)
                        {
                            iPQ.Remove(pair.Key);
                            iPQ.Add(NewCost, e.To);
                        }
                    }
                    m_searchFrontier[e.To] = e;
                }
            }
        }
    }
    /// <summary>
    /// 深度优先搜索
    /// </summary>
    /// <returns></returns>
    private bool DFSSearch()
    {
        m_visitedNodes.Clear();
        m_route.Clear();
        //创建堆栈用来保存边的指针
        Stack <GraphEdge> edgeStack = new Stack <GraphEdge>();
        //创建一个哑边并入栈
        GraphEdge dummyEdge = new GraphEdge(sourceNodeIndex, sourceNodeIndex, 0);

        edgeStack.Push(dummyEdge);
        while (edgeStack.Count > 0)
        {
            //取下一条边
            GraphEdge next = edgeStack.Pop();
            //记录这条边指向的节点的父节点
            m_route.Add(next.To, next.From);
            //并标记指向的节点为已访问
            m_visitedNodes.Add(next.To, NodeVisitType.visited);
            if (next.To == targetNodeIndex)
            {
                return(true);
            }
            //将这条边指向的节点的所有关联的边入栈
            //只要关联的边指向的节点没有被访问过
            foreach (GraphEdge e in m_graph.GetRelatedEdges(next.To))
            {
                if (!m_visitedNodes.ContainsKey(e.To))
                {
                    edgeStack.Push(e);
                }
            }
        }

        //没有路径到达目标节点
        return(false);
    }