// 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 } } } }
public DijkstraAllPairsSP(EdgeWeightedDigraph G) { all = new DijkstraSP[G.GetVertices()]; for (int v = 0; v < G.GetVertices(); v++) { all[v] = new DijkstraSP(G, v); } }
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); } } }
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); } } }
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); } } }
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); }
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(); }
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); } }
// 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; }
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); } } }
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(); }