Esempio n. 1
0
        public static void MainTest(string[] args)
        {
            TextInput           input = new TextInput(args[0]);
            int                 s     = int.Parse(args[1]);
            EdgeWeightedDigraph G     = new EdgeWeightedDigraph(input);

            // find shortest path from s to each other vertex in DAG
            AcyclicSP sp = new AcyclicSP(G, s);

            for (int v = 0; v < G.V; v++)
            {
                if (sp.HasPathTo(v))
                {
                    Console.Write("{0} to {1} ({2:F2})  ", s, v, sp.DistTo(v));
                    foreach (DirectedEdge e in sp.PathTo(v))
                    {
                        Console.Write(e + "   ");
                    }
                    Console.WriteLine();
                }
                else
                {
                    Console.Write("{0} to {1} no path\n", s, v);
                }
            }
        }
Esempio n. 2
0
        public static void MainTest(string[] args)
        {
            TextInput           input = new TextInput(args[0]);
            EdgeWeightedDigraph G     = new EdgeWeightedDigraph(input);
            int s = int.Parse(args[1]);

            // compute shortest paths
            DijkstraSP sp = new DijkstraSP(G, s);

            // print shortest path
            for (int t = 0; t < G.V; t++)
            {
                if (sp.HasPathTo(t))
                {
                    Console.Write("{0} to {1} ({2:F2})  ", s, t, sp.DistTo(t));
                    foreach (DirectedEdge e in sp.PathTo(t))
                    {
                        Console.Write(e + "   ");
                    }
                    Console.WriteLine();
                }
                else
                {
                    Console.Write("{0} to {1} no path\n", s, t);
                }
            }
        }
Esempio n. 3
0
 // relax vertex v and put other endpoints on queue if changed
 private void relax(EdgeWeightedDigraph G, int v)
 {
     foreach (DirectedEdge e in G.Adj(v))
     {
         int w = e.To;
         if (distTo[w] > distTo[v] + e.Weight)
         {
             distTo[w] = distTo[v] + e.Weight;
             edgeTo[w] = e;
             if (!onQueue[w])
             {
                 queue.Enqueue(w);
                 onQueue[w] = true;
             }
         }
         if (cost++ % G.V == 0)
         {
             findNegativeCycle();
             if (HasNegativeCycle)
             {
                 return;          // found a negative cycle
             }
         }
     }
 }
Esempio n. 4
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));
        }
Esempio n. 5
0
        private DirectedEdge[] edgeTo; // edgeTo[v] = last edge on shortest s->v path

        /// <summary>Computes a shortest paths tree from <c>s</c> to every other vertex in
        /// the directed acyclic graph <c>G</c>.</summary>
        /// <param name="G">the acyclic digraph</param>
        /// <param name="s">the source vertex</param>
        /// <exception cref="ArgumentException">if the digraph is not acyclic</exception>
        /// <exception cref="ArgumentException">unless 0 &lt;= <c>s</c> &lt;= <c>V</c> - 1</exception>
        ///
        public AcyclicSP(EdgeWeightedDigraph G, int s)
        {
            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;

            // visit vertices in toplogical order
            Topological topological = new Topological(G);

            if (!topological.HasOrder)
            {
                throw new ArgumentException("Digraph is not acyclic.");
            }
            foreach (int v in topological.Order())
            {
                foreach (DirectedEdge e in G.Adj(v))
                {
                    relax(e);
                }
            }
        }
Esempio n. 6
0
        // find shortest augmenting path and upate
        private void augment()
        {
            // build residual graph
            EdgeWeightedDigraph G = new EdgeWeightedDigraph(2 * N + 2);
            int s = 2 * N, t = 2 * N + 1;

            for (int i = 0; i < N; i++)
            {
                if (xy[i] == UNMATCHED)
                {
                    G.AddEdge(new DirectedEdge(s, i, 0.0));
                }
            }
            for (int j = 0; j < N; j++)
            {
                if (yx[j] == UNMATCHED)
                {
                    G.AddEdge(new DirectedEdge(N + j, t, py[j]));
                }
            }
            for (int i = 0; i < N; i++)
            {
                for (int j = 0; j < N; j++)
                {
                    if (xy[i] == j)
                    {
                        G.AddEdge(new DirectedEdge(N + j, i, 0.0));
                    }
                    else
                    {
                        G.AddEdge(new DirectedEdge(i, N + j, reducedCost(i, j)));
                    }
                }
            }

            // compute shortest path from s to every other vertex
            DijkstraSP spt = new DijkstraSP(G, s);

            // augment along alternating path
            foreach (DirectedEdge e in spt.PathTo(t))
            {
                int i = e.From, j = e.To - N;
                if (i < N)
                {
                    xy[i] = j;
                    yx[j] = i;
                }
            }

            // update dual variables
            for (int i = 0; i < N; i++)
            {
                px[i] += spt.DistTo(i);
            }
            for (int j = 0; j < N; j++)
            {
                py[j] += spt.DistTo(N + j);
            }
        }
Esempio n. 7
0
 /// <summary>
 /// Computes a shortest paths tree from each vertex to to every other vertex in
 /// the edge-weighted digraph <c>G</c>.</summary>
 /// <param name="G">the edge-weighted digraph</param>
 /// <exception cref="ArgumentException">if an edge weight is negative</exception>
 /// <exception cref="ArgumentException">unless 0 &lt;= <c>s</c> &lt;= <c>V</c> - 1</exception>
 ///
 public DijkstraAllPairsSP(EdgeWeightedDigraph G)
 {
     all = new DijkstraSP[G.V];
     for (int v = 0; v < G.V; v++)
     {
         all[v] = new DijkstraSP(G, v);
     }
 }
Esempio n. 8
0
        public static void MainTest(string[] args)
        {
            // create random DAG with V vertices and E edges; then add F random edges
            int V = int.Parse(args[0]);
            int E = int.Parse(args[1]);
            int F = int.Parse(args[2]);
            EdgeWeightedDigraph G = new EdgeWeightedDigraph(V);

            int[] vertices = new int[V];
            for (int i = 0; i < V; i++)
            {
                vertices[i] = i;
            }
            StdRandom.Shuffle(vertices);
            for (int i = 0; i < E; i++)
            {
                int v, w;
                do
                {
                    v = StdRandom.Uniform(V);
                    w = StdRandom.Uniform(V);
                } while (v >= w);
                double weight = StdRandom.Uniform();
                G.AddEdge(new DirectedEdge(v, w, weight));
            }

            // add F extra edges
            for (int i = 0; i < F; i++)
            {
                int    v      = StdRandom.Uniform(V);
                int    w      = StdRandom.Uniform(V);
                double weight = StdRandom.Uniform(0.0, 1.0);
                G.AddEdge(new DirectedEdge(v, w, weight));
            }

            Console.WriteLine(G);

            // find a directed cycle
            EdgeWeightedDirectedCycle finder = new EdgeWeightedDirectedCycle(G);

            if (finder.HasCycle)
            {
                Console.Write("Cycle: ");
                foreach (DirectedEdge e in finder.GetCycle())
                {
                    Console.Write(e + " ");
                }
                Console.WriteLine();
            }

            // or give topologial sort
            else
            {
                Console.WriteLine("No directed cycle");
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Determines whether the edge-weighted digraph <c>G</c> has a topological
        /// order and, if so, finds such an order.</summary>
        /// <param name="G">the edge-weighted digraph</param>
        ///
        public Topological(EdgeWeightedDigraph G)
        {
            EdgeWeightedDirectedCycle finder = new EdgeWeightedDirectedCycle(G);

            if (!finder.HasCycle)
            {
                DepthFirstOrder dfs = new DepthFirstOrder(G);
                order = dfs.ReversePost();
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Determines whether the edge-weighted digraph <c>G</c> has a
        /// topological order and, if so, finds such a topological order.</summary>
        /// <param name="G">the digraph</param>
        ///
        public TopologicalX(EdgeWeightedDigraph G)
        {
            // indegrees of remaining vertices
            int[] indegree = new int[G.V];
            for (int v = 0; v < G.V; v++)
            {
                indegree[v] = G.Indegree(v);
            }

            // initialize
            rank  = new int[G.V];
            order = new LinkedQueue <int>();
            int count = 0;

            // initialize queue to contain all vertices with indegree = 0
            LinkedQueue <int> queue = new LinkedQueue <int>();

            for (int v = 0; v < G.V; v++)
            {
                if (indegree[v] == 0)
                {
                    queue.Enqueue(v);
                }
            }

            for (int j = 0; !queue.IsEmpty; j++)
            {
                int v = queue.Dequeue();
                order.Enqueue(v);
                rank[v] = count++;
                foreach (DirectedEdge e in G.Adj(v))
                {
                    int w = e.To;
                    indegree[w]--;
                    if (indegree[w] == 0)
                    {
                        queue.Enqueue(w);
                    }
                }
            }

            // there is a directed cycle in subgraph of vertices with indegree >= 1.
            if (count != G.V)
            {
                order = null;
            }

            Debug.Assert(check(G));
        }
Esempio n. 11
0
        // certify that digraph is acyclic
        private bool check(EdgeWeightedDigraph G)
        {
            // digraph is acyclic
            if (HasOrder)
            {
                // check that ranks are a permutation of 0 to V-1
                bool[] found = new bool[G.V];
                for (int i = 0; i < G.V; i++)
                {
                    found[Rank(i)] = true;
                }
                for (int i = 0; i < G.V; i++)
                {
                    if (!found[i])
                    {
                        Console.Error.WriteLine("No vertex with rank " + i);
                        return(false);
                    }
                }

                // check that ranks provide a valid topological order
                for (int v = 0; v < G.V; v++)
                {
                    foreach (DirectedEdge e in G.Adj(v))
                    {
                        int w = e.To;
                        if (Rank(v) > Rank(w))
                        {
                            Console.Error.WriteLine("{0}-{1}: rank({2}) = {3}, rank({4}) = {5}\n",
                                                    v, w, v, Rank(v), w, Rank(w));
                            return(false);
                        }
                    }
                }

                // check that order() is consistent with rank()
                int r = 0;
                foreach (int v in Order())
                {
                    if (Rank(v) != r)
                    {
                        Console.Error.WriteLine("Order() and Rank() inconsistent");
                        return(false);
                    }
                    r++;
                }
            }
            return(true);
        }
Esempio n. 12
0
 /// <summary>
 /// Determines a depth-first order for the edge-weighted digraph <c>G</c>.</summary>
 /// <param name="G">the edge-weighted digraph</param>
 ///
 public DepthFirstOrder(EdgeWeightedDigraph G)
 {
     pre       = new int[G.V];
     post      = new int[G.V];
     postorder = new LinkedQueue <int>();
     preorder  = new LinkedQueue <int>();
     marked    = new bool[G.V];
     for (int v = 0; v < G.V; v++)
     {
         if (!marked[v])
         {
             dfs(G, v);
         }
     }
 }
Esempio n. 13
0
 // run DFS in edge-weighted digraph G from vertex v and compute preorder/postorder
 private void dfs(EdgeWeightedDigraph G, int v)
 {
     marked[v] = true;
     pre[v]    = preCounter++;
     preorder.Enqueue(v);
     foreach (DirectedEdge e in G.Adj(v))
     {
         int w = e.To;
         if (!marked[w])
         {
             dfs(G, w);
         }
     }
     postorder.Enqueue(v);
     post[v] = postCounter++;
 }
Esempio n. 14
0
        private LinkedStack <DirectedEdge> cycle; // directed cycle (or null if no such cycle)

        /// <summary>
        /// Determines whether the edge-weighted digraph <c>G</c> has a directed cycle and,
        /// if so, finds such a cycle.</summary>
        /// <param name="G">the edge-weighted digraph</param>
        ///
        public EdgeWeightedDirectedCycle(EdgeWeightedDigraph G)
        {
            marked  = new bool[G.V];
            onStack = new bool[G.V];
            edgeTo  = new DirectedEdge[G.V];
            for (int v = 0; v < G.V; v++)
            {
                if (!marked[v])
                {
                    dfs(G, v);
                }
            }

            // check that digraph has a cycle
            Debug.Assert(check(G));
        }
Esempio n. 15
0
        // by finding a cycle in predecessor graph
        private void findNegativeCycle()
        {
            int V = edgeTo.Length;
            EdgeWeightedDigraph spt = new EdgeWeightedDigraph(V);

            for (int v = 0; v < V; v++)
            {
                if (edgeTo[v] != null)
                {
                    spt.AddEdge(edgeTo[v]);
                }
            }

            EdgeWeightedDirectedCycle finder = new EdgeWeightedDirectedCycle(spt);

            cycle = finder.GetCycle();
        }
Esempio n. 16
0
File: CPM.cs Progetto: zzhi/Algs4Net
        public static void MainTest(string[] args)
        {
            TextInput StdIn = new TextInput();
            // number of jobs
            int N = StdIn.ReadInt();

            // source and sink
            int source = 2 * N;
            int sink   = 2 * N + 1;

            // build network
            EdgeWeightedDigraph G = new EdgeWeightedDigraph(2 * N + 2);

            for (int i = 0; i < N; i++)
            {
                double duration = StdIn.ReadDouble();
                G.AddEdge(new DirectedEdge(source, i, 0.0));
                G.AddEdge(new DirectedEdge(i + N, sink, 0.0));
                G.AddEdge(new DirectedEdge(i, i + N, duration));

                // precedence constraints
                int M = StdIn.ReadInt();
                for (int j = 0; j < M; j++)
                {
                    int precedent = StdIn.ReadInt();
                    G.AddEdge(new DirectedEdge(N + i, precedent, 0.0));
                }
            }

            // compute longest path
            AcyclicLP lp = new AcyclicLP(G, source);

            // print results
            Console.WriteLine(" job   start  finish");
            Console.WriteLine("--------------------");
            for (int i = 0; i < N; i++)
            {
                Console.Write("{0,4} {1,7:F1} {2,7:F1}\n", i, lp.DistTo(i), lp.DistTo(i + N));
            }
            Console.Write("Finish time: {0,7:F1}\n", lp.DistTo(sink));
        }
Esempio n. 17
0
 /// <summary>
 /// Initializes a new edge-weighted digraph that is a deep copy of <c>G</c>.</summary>
 /// <param name="G">the edge-weighted digraph to copy</param>
 ///
 public EdgeWeightedDigraph(EdgeWeightedDigraph G) : this(G.V)
 {
     numEdges = G.E;
     for (int v = 0; v < G.V; v++)
     {
         indegree[v] = G.Indegree(v);
     }
     for (int v = 0; v < G.V; v++)
     {
         // reverse so that adjacency list is in same order as original
         Stack <DirectedEdge> reverse = new Stack <DirectedEdge>();
         foreach (DirectedEdge e in G.adj[v])
         {
             reverse.Push(e);
         }
         foreach (DirectedEdge e in reverse)
         {
             adj[v].Add(e);
         }
     }
 }
Esempio n. 18
0
        public static void MainTest(string[] args)
        {
            TextInput StdIn = new TextInput();
            // V currencies
            int V = StdIn.ReadInt();

            string[] name = new string[V];

            // create complete network
            EdgeWeightedDigraph G = new EdgeWeightedDigraph(V);

            for (int v = 0; v < V; v++)
            {
                name[v] = StdIn.ReadString();
                for (int w = 0; w < V; w++)
                {
                    double       rate = StdIn.ReadDouble();
                    DirectedEdge e    = new DirectedEdge(v, w, -Math.Log(rate));
                    G.AddEdge(e);
                }
            }

            // find negative cycle
            BellmanFordSP spt = new BellmanFordSP(G, 0);

            if (spt.HasNegativeCycle)
            {
                double stake = 1000.0;
                foreach (DirectedEdge e in spt.GetNegativeCycle())
                {
                    Console.Write("{0,10:F5} {1} ", stake, name[e.From]);
                    stake *= Math.Exp(-e.Weight);
                    Console.Write("= {0,10:F5} {1}\n", stake, name[e.To]);
                }
            }
            else
            {
                Console.WriteLine("No arbitrage opportunity");
            }
        }
Esempio n. 19
0
 // check optimality conditions
 private bool check(EdgeWeightedDigraph G, int s)
 {
     // no negative cycle
     if (!HasNegativeCycle)
     {
         for (int v = 0; v < G.V; v++)
         {
             foreach (DirectedEdge e in G.Adj(v))
             {
                 int w = e.To;
                 for (int i = 0; i < G.V; i++)
                 {
                     if (distTo[i, w] > distTo[i, v] + e.Weight)
                     {
                         Console.Error.WriteLine("edge " + e + " is eligible");
                         return(false);
                     }
                 }
             }
         }
     }
     return(true);
 }
Esempio n. 20
0
 /// <summary>
 /// Returns a negative cycle, or <c>null</c> if there is no such cycle.</summary>
 /// <returns>a negative cycle as an iterable of edges,
 /// or <c>null</c> if there is no such cycle</returns>
 ///
 public IEnumerable <DirectedEdge> NegativeCycle()
 {
     for (int v = 0; v < distTo.Length; v++)
     {
         // negative cycle in v's predecessor graph
         if (distTo[v, v] < 0.0)
         {
             int V = edgeTo.Length;
             EdgeWeightedDigraph spt = new EdgeWeightedDigraph(V);
             for (int w = 0; w < V; w++)
             {
                 if (edgeTo[v, w] != null)
                 {
                     spt.AddEdge(edgeTo[v, w]);
                 }
             }
             EdgeWeightedDirectedCycle finder = new EdgeWeightedDirectedCycle(spt);
             Debug.Assert(finder.HasCycle);
             return(finder.GetCycle());
         }
     }
     return(null);
 }
Esempio n. 21
0
        public static void MainTest(string[] args)
        {
            EdgeWeightedDigraph G = new EdgeWeightedDigraph(new TextInput(args[0]));

            int       s  = int.Parse(args[1]);
            AcyclicLP lp = new AcyclicLP(G, s);

            for (int v = 0; v < G.V; v++)
            {
                if (lp.HasPathTo(v))
                {
                    Console.Write("{0} to {1} ({2:F2})  ", s, v, lp.DistTo(v));
                    foreach (DirectedEdge e in lp.PathTo(v))
                    {
                        Console.Write(e + "   ");
                    }
                    Console.WriteLine();
                }
                else
                {
                    Console.Write("{0} to {0}         no path\n", s, v);
                }
            }
        }
Esempio n. 22
0
        // check that algorithm computes either the topological order or finds a directed cycle
        private void dfs(EdgeWeightedDigraph G, int v)
        {
            onStack[v] = true;
            marked[v]  = true;
            foreach (DirectedEdge e in G.Adj(v))
            {
                int w = e.To;

                // short circuit if directed cycle found
                if (cycle != null)
                {
                    return;
                }
                else if (!marked[w])
                {
                    //found new vertex, so recur
                    edgeTo[w] = e;
                    dfs(G, w);
                }
                else if (onStack[w])
                {
                    // trace back directed cycle
                    cycle = new LinkedStack <DirectedEdge>();
                    DirectedEdge eTemp = e;
                    while (eTemp.From != w)
                    {
                        cycle.Push(eTemp);
                        eTemp = edgeTo[eTemp.From];
                    }
                    cycle.Push(eTemp);
                    return;
                }
            }

            onStack[v] = false;
        }
Esempio n. 23
0
        public static void MainTest(string[] args)
        {
            TextInput           input = new TextInput(args[0]);
            EdgeWeightedDigraph G     = new EdgeWeightedDigraph(input);
            int s = int.Parse(args[1]);

            BellmanFordSP sp = new BellmanFordSP(G, s);

            // print negative cycle
            if (sp.HasNegativeCycle)
            {
                foreach (DirectedEdge e in sp.GetNegativeCycle())
                {
                    Console.WriteLine(e);
                }
            }
            else // print shortest paths
            {
                for (int v = 0; v < G.V; v++)
                {
                    if (sp.HasPathTo(v))
                    {
                        Console.Write("{0} to {1} ({2:F2})  ", s, v, sp.DistTo(v));
                        foreach (DirectedEdge e in sp.PathTo(v))
                        {
                            Console.Write(e + "   ");
                        }
                        Console.WriteLine();
                    }
                    else
                    {
                        Console.Write("{0} to {1}: no path\n", s, v);
                    }
                }
            }
        }
Esempio n. 24
0
        private IEnumerable <DirectedEdge> cycle; // negative cycle (or null if no such cycle)

        /// <summary>Computes a shortest paths tree from <c>s</c> to every other vertex in
        /// the edge-weighted digraph <c>G</c>.</summary>
        /// <param name="G">the acyclic digraph</param>
        /// <param name="s">the source vertex</param>
        /// <exception cref="ArgumentException">unless 0 &lt;= <c>s</c> &lt;= <c>V</c> - 1</exception>
        ///
        public BellmanFordSP(EdgeWeightedDigraph G, int s)
        {
            distTo  = new double[G.V];
            edgeTo  = new DirectedEdge[G.V];
            onQueue = new bool[G.V];
            for (int v = 0; v < G.V; v++)
            {
                distTo[v] = double.PositiveInfinity;
            }
            distTo[s] = 0.0;

            // Bellman-Ford algorithm
            queue = new LinkedQueue <int>();
            queue.Enqueue(s);
            onQueue[s] = true;
            while (!queue.IsEmpty && !HasNegativeCycle)
            {
                int v = queue.Dequeue();
                onQueue[v] = false;
                relax(G, v);
            }

            Debug.Assert(check(G, s));
        }
Esempio n. 25
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);
        }
Esempio n. 26
0
        // check optimality conditions: either
        // (i) there exists a negative cycle reacheable from s
        //     or
        // (ii)  for all edges e = v->w:            distTo[w] <= distTo[v] + e.Weight
        // (ii') for all edges e = v->w on the SPT: distTo[w] == distTo[v] + e.Weight
        private bool check(EdgeWeightedDigraph G, int s)
        {
            // has a negative cycle
            if (HasNegativeCycle)
            {
                double weight = 0.0;
                foreach (DirectedEdge e in GetNegativeCycle())
                {
                    weight += e.Weight;
                }
                if (weight >= 0.0)
                {
                    Console.Error.WriteLine("error: weight of negative cycle = " + weight);
                    return(false);
                }
            }

            // no negative cycle reachable from source
            else
            {
                // check that distTo[v] and edgeTo[v] are consistent
                if (distTo[s] != 0.0 || edgeTo[s] != null)
                {
                    Console.Error.WriteLine("distanceTo[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);
                    }
                }
            }

            //Console.WriteLine("Satisfies optimality conditions");
            return(true);
        }
Esempio n. 27
0
        public static void MainTest(string[] args)
        {
            EdgeWeightedDigraph G = new EdgeWeightedDigraph(new TextInput(args[0]));

            Console.WriteLine(G);
        }