// relax edge e private void relax(DirectedEdge e) { int v = e.from(), w = e.to(); if (distTo[w] > distTo[v] + e.Weight()) { distTo[w] = distTo[v] + e.Weight(); edgeTo[w] = e; } }
// relax edge e and update pq if changed private void relax(DirectedEdge e) { int v = e.from(), w = e.to(); if (distTo[w] > distTo[v] + e.Weight()) { distTo[w] = distTo[v] + e.Weight(); edgeTo[w] = e; if (pq.contains(w)) { pq.decreaseKey(w, distTo[w]); } else { pq.insert(w, distTo[w]); } } }
void Start() { string[] lines = txt.text.Split(new char[] { '\n' }); // V currencies int V = int.Parse(lines[0]); string[] name = new string[V]; // create complete network EdgeWeightedDigraph G = new EdgeWeightedDigraph(V); for (int v = 0; v < V; v++) { string[] lineStrs = lines[v + 1].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); name[v] = lineStrs[0]; for (int w = 0; w < V; w++) { double rate = double.Parse(lineStrs[w + 1]); 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.negativeCycle()) { string str = (stake + " " + name[e.from()] + " "); stake *= Math.Exp(-e.Weight()); str += ("= " + stake + " " + name[e.to()] + "\n"); print(str); } print("以1000元为本金,该负权重环一圈套利" + (stake - 1000)); } else { print("No arbitrage opportunity"); } }
// 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 negativeCycle()) { weight += e.Weight(); } if (weight >= 0.0) { throw new System.Exception("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) { throw new System.Exception("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) { throw new System.Exception("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]) { throw new System.Exception("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]) { throw new System.Exception("edge " + e + " on shortest path not tight"); return false; } } } print("Satisfies optimality conditions"); return true; }
private bool Check(EdgeWeightedDigraph G, int s) { // check that edge weights are nonnegative foreach (DirectedEdge e in G.edges()) { if (e.Weight() < 0) { throw new System.Exception("negative edge weight detected"); return(false); } } // check that distTo[v] and edgeTo[v] are consistent if (distTo[s] != 0.0 || edgeTo[s] != null) { throw new System.Exception("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) { throw new System.Exception("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]) { throw new System.Exception("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]) { throw new System.Exception("edge " + e + " on shortest path not tight"); return(false); } } return(true); }