Example #1
0
        /// <summary>
        /// 松弛图g中的顶点v
        /// </summary>
        /// <param name="g"></param>
        /// <param name="v"></param>
        private void relax(EdgeDirectedWeightedDirgraph g, int v)
        {
            IEnumerator ie = g.adj(v).GetEnumerator();

            while (ie.MoveNext())
            {
                EdgeDirected e = (EdgeDirected)ie.Current;
                // 获取到该边的终点w
                int w = e.to();
                // 通过松弛技术,判断从起点s到顶点w的最短路径是否需要先从顶点s到顶点v,然后再由定点v到顶点w
                if (this.distTo(v) + e.weight() < this.distTo(w))
                {
                    this.distToDouble[w] = this.distToDouble[v] + e.weight();
                    this.edgeTo[w]       = e;
                    // 判断pq中是否已经存在在顶点w,如果存在,则更新新权重,如果不存在则直接添加
                    if (this.pq.contains(w))
                    {
                        this.pq.changeItem(w, this.distTo(w));
                    }
                    else
                    {
                        this.pq.insert(w, distTo(w));
                    }
                }
            }
        }
        /// <summary>
        /// 最短路径
        /// </summary>
        private static void DijksraSPTest()
        {
            // 创建加权有向图
            EdgeDirectedWeightedDirgraph graph = new EdgeDirectedWeightedDirgraph(8);

            graph.addEdge(new EdgeDirected(4, 5, 0.35f));
            graph.addEdge(new EdgeDirected(5, 4, 0.35f));
            graph.addEdge(new EdgeDirected(4, 7, 0.37f));
            graph.addEdge(new EdgeDirected(5, 7, 0.28f));
            graph.addEdge(new EdgeDirected(7, 5, 0.28f));
            graph.addEdge(new EdgeDirected(5, 1, 0.32f));
            graph.addEdge(new EdgeDirected(0, 4, 0.38f));
            graph.addEdge(new EdgeDirected(0, 2, 0.26f));
            graph.addEdge(new EdgeDirected(7, 3, 0.39f));
            graph.addEdge(new EdgeDirected(1, 3, 0.29f));
            graph.addEdge(new EdgeDirected(2, 7, 0.34f));
            graph.addEdge(new EdgeDirected(6, 2, 0.40f));
            graph.addEdge(new EdgeDirected(3, 6, 0.52f));
            graph.addEdge(new EdgeDirected(6, 0, 0.58f));
            graph.addEdge(new EdgeDirected(6, 4, 0.93f));
            // 创建 DijksraSP 对象 查找最短路径
            int       start   = 0;
            DijksraSP dijksra = new DijksraSP(graph, start);
            // 查找最短路径  0->6
            int end = 6;
            QueueList <EdgeDirected> allEdges = dijksra.pathTo(end);

            // 遍历打印
            if (allEdges == null)
            {
                Console.WriteLine("not path to " + end);
            }
            else
            {
                IEnumerator ie = allEdges.GetEnumerator();
                while (ie.MoveNext())
                {
                    EdgeDirected e = (EdgeDirected)ie.Current;
                    Console.WriteLine(e.from() + " -> " + e.to() + " : " + e.weight().ToString("F2"));
                }
            }
        }
Example #3
0
 /// <summary>
 /// 根据加权有向图g和顶点s创建一个计算顶点为s的最短路径树对象
 /// </summary>
 /// <param name="g"></param>
 /// <param name="s"></param>
 public DijksraSP(EdgeDirectedWeightedDirgraph g, int s)
 {
     // 初始化 edgeTo
     this.edgeTo = new EdgeDirected[g.countV()];
     // 初始化 distToDouble
     this.distToDouble = new double[g.countV()];
     for (int i = 0; i < this.distToDouble.Length; i++)
     {
         this.distToDouble[i] = Double.PositiveInfinity;
     }
     // 初始化 pq
     this.pq = new IndexMinPriorityQueue <double>(g.countV());
     // 找到图g中顶点s为起点的最短路径树
     // 默认让顶点s进入到最短路径树中
     this.distToDouble[s] = 0.0f;
     this.pq.insert(s, 0.0f);
     // 遍历pq
     while (!this.pq.isEmpty())
     {
         relax(g, this.pq.delMinIndex());
     }
 }