Ejemplo n.º 1
0
        private IndexMinPQ <double> pq; // priority queue of vertices

        /// <summary>Computes a shortest-paths tree from the source vertex <c>s</c> to every other
        /// vertex in the edge-weighted digraph <c>G</c>.</summary>
        /// <param name="G">the edge-weighted digraph</param>
        /// <param name="s">the source vertex</param>
        /// <exception cref="ArgumentException">if an edge weight is negative</exception>
        /// <exception cref="ArgumentException">unless 0 &lt;= <c>s</c> &lt;=e <c>V</c> - 1</exception>
        ///
        public DijkstraSP(EdgeWeightedDigraph G, int s)
        {
            foreach (DirectedEdge e in G.Edges())
            {
                if (e.Weight < 0)
                {
                    throw new ArgumentException("edge " + e + " has negative weight");
                }
            }

            distTo = new double[G.V];
            edgeTo = new DirectedEdge[G.V];
            for (int v = 0; v < G.V; v++)
            {
                distTo[v] = double.PositiveInfinity;
            }
            distTo[s] = 0.0;

            // relax vertices in order of distance from s
            pq = new IndexMinPQ <double>(G.V);
            pq.Insert(s, distTo[s]);
            while (!pq.IsEmpty)
            {
                int v = pq.DelMin();
                foreach (DirectedEdge e in G.Adj(v))
                {
                    relax(e);
                }
            }

            // check optimality conditions
            Debug.Assert(check(G, s));
        }
Ejemplo n.º 2
0
        // check optimality conditions:
        // (i) for all edges e:            distTo[e.To] <= distTo[e.From] + e.Weight
        // (ii) for all edge e on the SPT: distTo[e.To] == distTo[e.From] + e.Weight
        private bool check(EdgeWeightedDigraph G, int s)
        {
            // check that edge weights are nonnegative
            foreach (DirectedEdge e in G.Edges())
            {
                if (e.Weight < 0)
                {
                    Console.Error.WriteLine("negative edge weight detected");
                    return(false);
                }
            }

            // check that distTo[v] and edgeTo[v] are consistent
            if (distTo[s] != 0.0 || edgeTo[s] != null)
            {
                Console.Error.WriteLine("distTo[s] and edgeTo[s] inconsistent");
                return(false);
            }
            for (int v = 0; v < G.V; v++)
            {
                if (v == s)
                {
                    continue;
                }
                if (edgeTo[v] == null && distTo[v] != double.PositiveInfinity)
                {
                    Console.Error.WriteLine("distTo[] and edgeTo[] inconsistent");
                    return(false);
                }
            }

            // check that all edges e = v->w satisfy distTo[w] <= distTo[v] + e.weight()
            for (int v = 0; v < G.V; v++)
            {
                foreach (DirectedEdge e in G.Adj(v))
                {
                    int w = e.To;
                    if (distTo[v] + e.Weight < distTo[w])
                    {
                        Console.Error.WriteLine("edge " + e + " not relaxed");
                        return(false);
                    }
                }
            }

            // check that all edges e = v->w on SPT satisfy distTo[w] == distTo[v] + e.weight()
            for (int w = 0; w < G.V; w++)
            {
                if (edgeTo[w] == null)
                {
                    continue;
                }
                DirectedEdge e = edgeTo[w];
                int          v = e.From;
                if (w != e.To)
                {
                    return(false);
                }
                if (distTo[v] + e.Weight != distTo[w])
                {
                    Console.Error.WriteLine("edge " + e + " on shortest path not tight");
                    return(false);
                }
            }
            return(true);
        }