// 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); } }
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"); } }
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)); }
// 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(); }
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"); } }
/// <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); }