/** * Unit tests the {@code TopologicalX} data type. * * @param args the command-line arguments */ public static void main(String[] args) { // create random DAG with V vertices and E edges; then add F random edges int V = Integer.parseInt(args[0]); int E = Integer.parseInt(args[1]); int F = Integer.parseInt(args[2]); Digraph G1 = DigraphGenerator.dag(V, E); // corresponding edge-weighted digraph EdgeWeightedDigraph G2 = new EdgeWeightedDigraph(V); for (int v = 0; v < G1.V(); v++) for (int w : G1.adj(v)) G2.addEdge(new DirectedEdge(v, w, 0.0)); // add F extra edges for (int i = 0; i < F; i++) { int v = StdRandom.uniform(V); int w = StdRandom.uniform(V); G1.addEdge(v, w); G2.addEdge(new DirectedEdge(v, w, 0.0)); } StdOut.println(G1); StdOut.println(); StdOut.println(G2); // find a directed cycle TopologicalX topological1 = new TopologicalX(G1); if (!topological1.hasOrder()) { StdOut.println("Not a DAG"); } // or give topologial sort else { StdOut.print("Topological order: "); for (int v : topological1.order()) { StdOut.print(v + " "); } StdOut.println(); } // find a directed cycle TopologicalX topological2 = new TopologicalX(G2); if (!topological2.hasOrder()) { StdOut.println("Not a DAG"); } // or give topologial sort else { StdOut.print("Topological order: "); for (int v : topological2.order()) { StdOut.print(v + " "); } StdOut.println(); } }
/** * Reads the currency exchange table from standard input and * prints an arbitrage opportunity to standard output (if one exists). * * @param args the command-line arguments */ public static void main(String[] args) { // 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; for (DirectedEdge e : spt.negativeCycle()) { StdOut.printf("%10.5f %s ", stake, name[e.from()]); stake *= Math.exp(-e.weight()); StdOut.printf("= %10.5f %s\n", stake, name[e.to()]); } } else { StdOut.println("No arbitrage opportunity"); } }
/** * Unit tests the {@code EdgeWeightedDirectedCycle} data type. * * @param args the command-line arguments */ public static void main(String[] args) { // create random DAG with V vertices and E edges; then add F random edges int V = Integer.parseInt(args[0]); int E = Integer.parseInt(args[1]); int F = Integer.parseInt(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)); } StdOut.println(G); // find a directed cycle EdgeWeightedDirectedCycle finder = new EdgeWeightedDirectedCycle(G); if (finder.hasCycle()) { StdOut.print("Cycle: "); for (DirectedEdge e : finder.cycle()) { StdOut.print(e + " "); } StdOut.println(); } // or give topologial sort else { StdOut.println("No directed cycle"); } }
// 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.cycle(); }
// 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 for (DirectedEdge e : 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); }
/** * Reads the precedence constraints from standard input * and prints a feasible schedule to standard output. * * @param args the command-line arguments */ public static void main(String[] args) { // 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 StdOut.println(" job start finish"); StdOut.println("--------------------"); for (int i = 0; i < n; i++) { StdOut.printf("%4d %7.1f %7.1f\n", i, lp.distTo(i), lp.distTo(i+n)); } StdOut.printf("Finish time: %7.1f\n", lp.distTo(sink)); }
/** * Returns a negative cycle, or {@code null} if there is no such cycle. * @return a negative cycle as an iterable of edges, * or {@code null} if there is no such cycle */ public Iterable<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); assert finder.hasCycle(); return finder.cycle(); } } return null; }