private void Dfs(EdgeWeightedDigraph G, int v)//(加权有向图)寻找相连的顶点 { onStack[v] = true; marked[v] = true; foreach (DirectedEdge w in G.Adj(v)) { if (this.HasCycle()) { return; } else if (!marked[w.To()]) { edgeTo[w.To()] = v;//存储最先到达w.To()点的v点 Dfs(G, w.To()); } else if (onStack[w.To()]) { cycle = new Stack <int>(); for (int x = v; x != w.To(); x = edgeTo[x]) { cycle.Push(x); } cycle.Push(w.To()); cycle.Push(v); } } onStack[v] = false; }
public AcyclicLP(EdgeWeightedDigraph G) { edgeTo = new DirectedEdge[G.VNumber()]; distTo = new double[G.VNumber()]; for (int v = 0; v < G.VNumber(); v++) { distTo[v] = Double.NegativeInfinity; } Topological top = new Topological(G); /*起先并不知道图的拓扑排序顺序,因此无法得知起点位置, * 因此引入计数器n,判定拓扑排序起点,并将起点的distTo[]设置为0。 */ int n = 0; foreach (int v in top.Order()) { if (n == 0) { distTo[v] = 0.0; } Relax(G, v); n++; } }
public Topological(EdgeWeightedDigraph G) { DirectedCycle cycleFinder = new DirectedCycle(G); if (!cycleFinder.HasCycle()) { DepthFirstOrder dfs = new DepthFirstOrder(G); order = dfs.ReversePost(); } }
private void Relax(EdgeWeightedDigraph G, int v) { foreach (DirectedEdge e in G.Adj(v)) { int w = e.To(); if (distTo[w] > distTo[v] + e.Weight()) { distTo[w] = distTo[v] + e.Weight(); edgeTo[w] = e; } } }
public DirectedCycle(EdgeWeightedDigraph G) { onStack = new bool[G.VNumber()]; edgeTo = new int[G.VNumber()]; marked = new bool[G.VNumber()]; for (int v = 0; v < G.VNumber(); v++) { if (!marked[v]) { Dfs(G, v); } } }
private void Dfs(EdgeWeightedDigraph G, int v) { pre.enqueue(v); marked[v] = true; foreach (DirectedEdge 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.VNumber()]; for (int v = 0; v < G.VNumber(); v++) { if (!marked[v]) { Dfs(G, 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]); } } DirectedCycle cf = new DirectedCycle(spt); cycle = cf.Cycle(); }
public DijkstraSP(EdgeWeightedDigraph G, int s) { edgeTo = new DirectedEdge[G.VNumber()]; distTo = new double[G.VNumber()]; pq = new IndexMinPQ <double>(G.VNumber()); for (int v = 0; v < G.VNumber(); v++) { distTo[v] = Double.PositiveInfinity; } distTo[s] = 0.0; pq.Insert(s, 0.0); while (!pq.IsEmpty()) { Relax(G, pq.DelMin()); } }
private Stack <int> cycle; //edgeTo[]中的是否有负权重环 public BellmanFordSP(EdgeWeightedDigraph G, int s) { distTo = new double[G.VNumber()]; edgeTo = new DirectedEdge[G.VNumber()]; onQ = new bool[G.VNumber()]; queue = new Queue <int>(); for (int v = 0; v < G.VNumber(); v++) { distTo[v] = Double.PositiveInfinity; } distTo[s] = 0.0; queue.enqueue(s); onQ[s] = true; while (!queue.IsEmpty() && !HasNegativeCycle()) { int v = queue.dequeue(); onQ[v] = false; Relax(G, v); } }
private void Relax(EdgeWeightedDigraph G, int v) { foreach (DirectedEdge e in G.Adj(v)) {// v->w e:v和w相连的边 int w = e.To(); if (distTo[w] > distTo[v] + e.Weight()) {// 起点到达w点的路径 > 起点到达v的路径+e的权重 distTo[w] = distTo[v] + e.Weight(); edgeTo[w] = e; if (pq.Contains(w)) { pq.Change(w, distTo[w]); } else { pq.Insert(w, distTo[w]); } } } }
private void Relax(EdgeWeightedDigraph G, int v) { foreach (DirectedEdge e in G.Adj(v)) { int 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; } } if (cost++ % G.VNumber() == 0) { FindNegativeCycle();//寻找有向图中是否有负权重环,以保证循环能够结束 } } }