public static void Main(string[] args) { var N = Console.Read(); Console.ReadLine(); var G = new EdgeWeightedDigraph(2 * N + 2); var s = 2 * N; var t = 2 * N + 1; for (int i = 0; i < N; i++) { var a = Console.ReadLine().Split(' '); var duation = double.Parse(a[0]); G.AddEdge(new DirectedEdge(i, i + N, duation)); G.AddEdge(new DirectedEdge(s, i, 0.0)); G.AddEdge(new DirectedEdge(i + N, t, 0.0)); for (int j = 1; j < a.Length; j++) { var successor = int.Parse(a[j]); G.AddEdge(new DirectedEdge(i + N, successor, 0.0)); } } var lp = new AcyclicLP(G, s); Console.WriteLine("Start times: "); for (int i = 0; i < N; i++) { Console.Write("{0} : {1:f1}\n", i, lp.DistToW(i)); } Console.WriteLine("Finish time: {0:f1}", lp.DistToW(t)); }
public DijkstraAllPairsSP(EdgeWeightedDigraph G) { all = new DijkstraSP[G.V]; for (int v = 0; v < G.V; v++) { all[v] = new DijkstraSP(G, v); } }
public Topological(EdgeWeightedDigraph G) { var cycleFinder = new DirectedCycle(G); if (!cycleFinder.HasCycle()) { var dfs = new DepthFirstOrder(G); Order = dfs.ReversePost; } }
private void Relax(EdgeWeightedDigraph g, int v) { foreach (var e in g.adj[v]) { var w = e.To(); if (DistTo[w] < DistTo[v] + e.Weight) { DistTo[w] = DistTo[v] + e.Weight; EdgeTo[w] = e; } } }
public EdgeWeightedCycleFinder(EdgeWeightedDigraph G) { marked = new bool[G.V]; OnStack = new bool[G.V]; EdgeTo = new DirectedEdge[G.V]; for (int v = 0; v < G.V; v++) { if (!marked[v]) { DFS(G, v); } } }
public DirectedCycle(EdgeWeightedDigraph G) { Marked = new bool[G.V]; EdgeTo = new int[G.V]; OnStack = new bool[G.V]; for (int v = 0; v < G.V; v++) { if (!Marked[v]) { DFS(G, v); } } }
private void DFS(EdgeWeightedDigraph g, int v) { Pre.Enqueue(v); Marked[v] = true; foreach (var w in g.adj[v]) { if (!Marked[w.To()]) { DFS(g, w.To()); } } Post.Enqueue(v); ReversePost.Push(v); }
public DepthFirstOrder(EdgeWeightedDigraph G) { Pre = new Queue <int>(); Post = new Queue <int>(); ReversePost = new Stack <int>(); Marked = new bool[G.V]; for (int v = 0; v < G.V; v++) { if (!Marked[v]) { DFS(G, v); } } }
private void FindNegativeCycle() { var V = EdgeTo.Length; var spt = new EdgeWeightedDigraph(V); for (int v = 0; v < V; v++) { if (EdgeTo[v] != null) { spt.AddEdge(EdgeTo[v]); } } var cf = new EdgeWeightedCycleFinder(spt); Cycle = cf.Cycle; }
public AcyclicLP(EdgeWeightedDigraph G, int s) { EdgeTo = new DirectedEdge[G.V]; DistTo = new double[G.V]; for (int v = 0; v < G.V; v++) { DistTo[v] = double.NegativeInfinity; } DistTo[s] = 0.0; var top = new Topological(G); foreach (var v in top.Order) { Relax(G, v); } }
public DijkstraSP(EdgeWeightedDigraph G, int s) { EdgeTo = new DirectedEdge[G.V]; DistTo = new double[G.V]; pq = new SortedDictionary <int, double>(); for (int v = 0; v < G.V; v++) { DistTo[v] = double.PositiveInfinity; } DistTo[0] = 0.0; pq.Add(s, 0.0); //核心就是每次选出权重最小点来继续搜索 while (pq.Count > 0) { var min = pq.Min(); Relax(G, min.Key); } }
private void Relax(EdgeWeightedDigraph g, int v) { foreach (var e in g.adj[v]) { var w = e.To(); if (DistTo[w] > DistTo[v] + e.Weight) { DistTo[w] = DistTo[v] + e.Weight; EdgeTo[w] = e; if (pq.ContainsKey(w)) { pq[w] = DistTo[w]; } else { pq.Add(w, DistTo[w]); } } } }
public BellmanFordSP(EdgeWeightedDigraph G, int s) { DistTo = new double[G.V]; EdgeTo = new DirectedEdge[G.V]; OnQ = new bool[G.V]; queue = new Queue <int>(); for (int v = 0; v < G.V; v++) { DistTo[v] = double.PositiveInfinity; } this.s = s; DistTo[s] = 0.0; queue.Enqueue(s); OnQ[s] = true; while (queue.Count > 0 && !HasNegativeCycle()) { var v = queue.Dequeue(); OnQ[v] = false; Relax(G, v); } }
public static void Main(string[] args) { //using (var reader = new StreamReader("rates.txt")) { using (var reader = new StreamReader(args[0])) { var V = int.Parse(reader.ReadLine().Split(' ')[0]); var name = new string[V]; var G = new EdgeWeightedDigraph(V); for (int v = 0; v < V; v++) { var line = reader.ReadLine().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); name[v] = line[0]; for (int w = 0; w < V; w++) { var rate = double.Parse(line[w + 1]); if (rate != 1) { var e = new DirectedEdge(v, w, -Math.Log(rate)); Console.WriteLine("{0}-->{1} : {2}", v, w, -Math.Log(rate)); G.AddEdge(e); } } } var spt = new BellmanFordSP(G, 0); if (spt.HasNegativeCycle()) { var stake = 1000.0; foreach (var e in spt.NegativeCycle()) { Console.Write("{0:f5} {1} ", stake, name[e.From()]); stake *= Math.Exp(-e.Weight); Console.WriteLine("= {0:f5} {1}", stake, name[e.To()]); } } else { Console.WriteLine("No arbitrage opportunity"); } //Console.Read(); } }
private void Relax(EdgeWeightedDigraph G, int v) { foreach (var e in G.adj[v]) { var w = e.To(); if (DistTo[w] > DistTo[v] + e.Weight) { DistTo[w] = DistTo[v] + e.Weight; EdgeTo[w] = e; if (!OnQ[w]) { queue.Enqueue(w); OnQ[w] = true; } } //如果不存在从起点S可达的负权重环,算法会在进行v-1轮放松后结束, //因为所有最短路含有的边数都不大于v-1,所以进行V轮后就可以检查一次负权重环 if (++cost % G.V == 0) { FindNegativeCycle(); } } }