private void dfs(int v, DirectedWeightedEdgeGraph G) { marked[v] = true; onstack[v] = true; foreach (var e in G.GetAdj(v)) { var w = e.To(); if (cycle != null) { return; } else if (!marked[w]) { edgeTo[w] = e; dfs(w, G); } else if (onstack[w]) { cycle = new Stack <DirectedWeightedEdge>(); for (var ee = e; ee.From() != w; ee = edgeTo[e.From()]) { cycle.Push(e); } cycle.Push(e); } } onstack[v] = false; }
public AcyclicSP(DirectedWeightedEdgeGraph G, int s) { //从加权有向图中获取它的有向图,以供拓扑排序用 tmpG = new DirectGraph(G.GetV()); for (int v = 0; v < G.GetV(); v++) { foreach (var e in G.GetAdj(v)) { int to = e.To(); tmpG.AddAdj(v, to); } } int V = G.GetV(); edgeTo = new DirectedWeightedEdge[V]; distTo = new double[V]; for (int i = 0; i < V; i++) { distTo[i] = double.MaxValue; } distTo[s] = 0.0; Topological top = new Topological(tmpG); foreach (var v in top.Order) { relax(G, v); } }
protected void relax(DirectedWeightedEdgeGraph G, int v) { foreach (var e in G.GetAdj(v)) { int w = e.To(); if (distTo[w] > e.GetWeight() + distTo[v]) { edgeTo[w] = e; distTo[w] = e.GetWeight() + distTo[v]; } } }
public DirectedWeightedCycle(DirectedWeightedEdgeGraph G) { marked = new bool[G.GetV()]; onstack = new bool[G.GetV()]; edgeTo = new DirectedWeightedEdge[G.GetE()]; for (int v = 0; v < G.GetV(); v++) { if (!marked[v]) { dfs(v, G); } } }
/// <summary> /// 用edges[]中的边来构造一幅加权有向图来检测环——基本思路: /// 在图中dfs,判断到目前节点已被marked并且在栈中,就是一个环 /// </summary> private void findNegativeCycle() { int V = edges.Length; DirectedWeightedEdgeGraph G = new DirectedWeightedEdgeGraph(V); foreach (var e in edges)//用edges来构造一幅加权有向图 { if (e != null) { G.AddEdge(e); } } DirectedWeightedCycle dc = new DirectedWeightedCycle(G); cycle = dc.GetCycle();//疑问:貌似找到的不一定是负权重环???? }
private void relax(int v, DirectedWeightedEdgeGraph G) { foreach (var e in G.GetAdj(v)) { int w = e.To(); if (distTo[w] > distTo[v] + e.GetWeight()) //到w的已有距离大于新节点到他的距离+新节点已有的距离 { distTo[w] = distTo[v] + e.GetWeight(); //放松操作 edgeTo[w] = e; if (dic.ContainsKey(w)) { dic[w] = distTo[w]; //保存下来 } else { dic.Add(w, distTo[w]); } } } }
public Dijkstra(DirectedWeightedEdgeGraph G, int s) { distTo = new double[G.GetV()]; edgeTo = new DirectedWeightedEdge[G.GetE()]; dic = new Dictionary <int, double>(); for (int i = 0; i < distTo.Length; i++)//到所有顶点的距离初始化为最大值 { distTo[i] = double.MaxValue; } distTo[s] = 0; //从0节点开始 dic.Add(0, 0); while (dic.Count() > 0) //直到所有节点都处理完为止 { var minE = MinEdge(); //取出目前最短的路径的终点 dic.Remove(minE); relax(minE, G); //开始放松 } }
private void relax(int v, DirectedWeightedEdgeGraph G) { foreach (var e in G.GetAdj(v)) { int w = e.To(); if (disTo[w] > disTo[v] + e.GetWeight()) { disTo[w] = disTo[v] + e.GetWeight(); edges[w] = e; if (!inQueue[w]) { inQueue[w] = true; queue.Enqueue(w); } } if (cost++ % G.GetV() == 0) { findNegativeCycle(); } } }
public BellmanFord(DirectedWeightedEdgeGraph G, int s) { disTo = new double[G.GetV()]; edges = new DirectedWeightedEdge[G.GetE()]; inQueue = new bool[G.GetV()]; queue = new Queue <int>(); for (int i = 0; i < G.GetV(); i++) { disTo[i] = double.MaxValue; } disTo[s] = 0; inQueue[s] = true; queue.Enqueue(s); while (queue.Count() > 0 && !hasNegativeCycle())//没有负权重环出现 { int v = queue.Dequeue(); inQueue[v] = false; relax(v, G); } }