コード例 #1
0
 // relax vertex v and put other endpoints on queue if changed
 private void Relax(EdgeWeightedDigraph G, int v)
 {
     //for (DirectedEdge e : G.adj(v))
     foreach (DirectedEdge e in G.GetAdj(v))
     {
         int w = e.To();
         if (distTo[w] > distTo[v] + e.GetWeight())
         {
             distTo[w] = distTo[v] + e.GetWeight();
             edgeTo[w] = e;
             if (!onQueue[w])
             {
                 queue.Enqueue(w);
                 onQueue[w] = true;
             }
         }
         if (cost++ % G.GetVertices() == 0)
         {
             FindNegativeCycle();
             if (IsNegativeCycle())
             {
                 return;                     // found a negative cycle
             }
         }
     }
 }
コード例 #2
0
 public DijkstraAllPairsSP(EdgeWeightedDigraph G)
 {
     all = new DijkstraSP[G.GetVertices()];
     for (int v = 0; v < G.GetVertices(); v++)
     {
         all[v] = new DijkstraSP(G, v);
     }
 }
コード例 #3
0
 private Stack <DirectedEdge> cycle; // directed cycle (or null if no such cycle)
 public EdgeWeightedDirectedCycle(EdgeWeightedDigraph G)
 {
     marked  = new bool[G.GetVertices()];
     onStack = new bool[G.GetVertices()];
     edgeTo  = new DirectedEdge[G.GetVertices()];
     for (int v = 0; v < G.GetVertices(); v++)
     {
         if (!marked[v])
         {
             Dfs(G, v);
         }
     }
 }
コード例 #4
0
 public CycleFinder(EdgeWeightedDigraph G)
 {
     marked  = new bool[G.GetVertices()];
     onStack = new bool[G.GetVertices()];
     edgeTo  = new int[G.GetVertices()];
     for (int v = 0; v < G.GetVertices(); v++)
     {
         if (!marked[v] && cycle == null)
         {
             Dfs(G, v);
         }
     }
 }
コード例 #5
0
 public Topological(EdgeWeightedDigraph G)
 {
     Pre         = new Queue <int>();
     Post        = new Queue <int>();
     ReversePost = new Stack <int>();
     marked      = new bool[G.GetVertices()];
     for (int v = 0; v < G.GetVertices(); v++)
     {
         if (!marked[v])
         {
             Dfs(G, v);
         }
     }
 }
コード例 #6
0
 private void Dfs(EdgeWeightedDigraph G, int v)
 {
     marked[v] = true;
     Pre.Enqueue(v);
     foreach (DirectedEdge e in G.GetAdj(v))
     {
         int w = e.To();
         if (!marked[w])
         {
             Dfs(G, w);
         }
     }
     Post.Enqueue(v);
     ReversePost.Push(v);
 }
コード例 #7
0
        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();
        }
コード例 #8
0
        private IEnumerable <DirectedEdge> cycle; // negative cycle (or null if no such cycle)
                                                  // by finding a cycle in predecessor graph

        public BellmanFordSP(EdgeWeightedDigraph G, int s)
        {
            distTo  = new double[G.GetVertices()];
            edgeTo  = new DirectedEdge[G.GetVertices()];
            onQueue = new bool[G.GetVertices()];
            for (int v = 0; v < G.GetVertices(); v++)
            {
                distTo[v] = Double.PositiveInfinity;
            }
            distTo[s] = 0.0;

            // Bellman-Ford algorithm
            queue = new Queue <int>();
            queue.Enqueue(s);
            onQueue[s] = true;
            while (queue.Count != 0 && !IsNegativeCycle())
            {
                int v = queue.Dequeue();
                onQueue[v] = false;
                Relax(G, v);
            }
        }
コード例 #9
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.GetAdj(v))
            {
                int w = e.To();
                // short circuit if directed cycle found
                if (cycle != null)
                {
                    return;
                }
                // found new vertex, so recur
                else if (!marked[w])
                {
                    edgeTo[w] = e;
                    Dfs(G, w);
                }

                // trace back directed cycle
                else if (onStack[w])
                {
                    cycle = new Stack <DirectedEdge>();

                    DirectedEdge f = e;
                    while (f.From() != w)
                    {
                        cycle.Push(f);
                        f = edgeTo[f.From()];
                    }
                    cycle.Push(f);
                    return;
                }
            }
            onStack[v] = false;
        }
コード例 #10
0
        public AcyclicSP(EdgeWeightedDigraph G, int s)
        {
            distTo = new double[G.GetVertices()];
            edgeTo = new DirectedEdge[G.GetVertices()];
            for (int v = 0; v < G.GetVertices(); v++)
            {
                distTo[v] = Double.PositiveInfinity;
            }
            distTo[s] = 0.0;
            ValidateVertex(s);
            Topological topological = new Topological(G);

            if (!topological.IsOrder())
            {
                throw new ArgumentException("Digraph is not acyclic.");
            }
            foreach (int v in topological.ReversePost)
            {
                foreach (DirectedEdge e in G.GetAdj(v))
                {
                    Relax(e);
                }
            }
        }
コード例 #11
0
        static void Main(string[] args)
        {
            EdgeWeightedDigraph G        = new EdgeWeightedDigraph("tinyEWD.txt");
            DijkstraSP          dijkstra = new DijkstraSP(G, 0);

            if (dijkstra.HasPathTo(1))
            {
                Queue <DirectedEdge> path = new Queue <DirectedEdge>(dijkstra.GetPathTo(1));
                foreach (DirectedEdge e in path)
                {
                    Console.WriteLine(e.From() + " -> " + e.To());
                }
            }
            else
            {
                Console.WriteLine("no path");
            }
            // Cycles
            EdgeWeightedDigraph G1 = new EdgeWeightedDigraph("tinyEWD.txt");
            EdgeWeightedDigraph G2 = new EdgeWeightedDigraph("tinyEWDAG.txt"); // Acyclic WOrGraph
            CycleFinder         c1 = new CycleFinder(G1);
            CycleFinder         c2 = new CycleFinder(G2);

            if (c1.IsCycle())
            {
                Console.WriteLine("Cycle in tinyEWD yes");
            }
            else
            {
                Console.WriteLine("Cycle in tinyEWD no");
            }
            if (c2.IsCycle())
            {
                Console.WriteLine("Cycle in tinyEWDAG yes");
            }
            else
            {
                Console.WriteLine("Cycle in tinyEWDAG no");
            }
            // AcyclicSP
            Console.WriteLine("Acyclic ASP");
            AcyclicSP asp = new AcyclicSP(G2, 5);
            int       v   = 2;

            if (asp.IsPathTo(v))
            {
                Console.WriteLine("path from 5 to " + v);
                Queue <DirectedEdge> path = new Queue <DirectedEdge>(asp.GetPathTo(v));
                foreach (DirectedEdge e in path)
                {
                    Console.WriteLine(e.From() + " -> " + e.To());
                }
            }
            else
            {
                Console.WriteLine("no path from 5 to " + v);
            }
            // BellmanFord
            EdgeWeightedDigraph G3 = new EdgeWeightedDigraph("tinyEWDn.txt");
            BellmanFordSP       b  = new BellmanFordSP(G3, 0);

            if (!b.IsNegativeCycle())
            {
                Queue <DirectedEdge> q = new Queue <DirectedEdge>(b.PathTo(7));
                foreach (DirectedEdge e in q)
                {
                    Console.WriteLine(e.From() + " - > " + e.To());
                }
            }
            else
            {
                Console.WriteLine("There is negative cycle");
                Queue <DirectedEdge> q = new Queue <DirectedEdge>(b.GetNegativeCycle());
                foreach (DirectedEdge e in q)
                {
                    Console.WriteLine(e.From() + " - > " + e.To());
                }
            }
            //Console.WriteLine(G.ToString());
            Console.ReadLine();
        }