public BellmanFordShortestPathAlgorithm(EdgeWeightedDigraph graph, Int32 vertice) { this._distTo = new double[graph.VerticesCount]; this._edgeTo = new Edge[graph.VerticesCount]; this._onQueue = new Boolean[graph.VerticesCount]; for (int v = 0; v < graph.VerticesCount; v++) { this._distTo[v] = Double.PositiveInfinity; } this._distTo[vertice] = 0.0; this._queue = new AST.Queue <Int32>(); this._queue.Enqueue(vertice); this._onQueue[vertice] = true; while (!this._queue.IsEmpty && !this.HasNegativeCycle) { Int32 v = this._queue.Dequeue(); this._onQueue[v] = false; this.Relax(graph, v); } }
private void Relax(EdgeWeightedDigraph graph, Int32 vertice) { foreach (Edge edge in graph.GetAdjacentVertices(vertice)) { Int32 target = edge.Target; if (this._distTo[target] > this._distTo[vertice] + edge.Weight) { this._distTo[target] = this._distTo[vertice] + edge.Weight; this._edgeTo[target] = edge; if (!this._onQueue[target]) { this._queue.Enqueue(target); this._onQueue[target] = true; } } if (this._cost++ % graph.VerticesCount == 0) { this.FindNegativeCycle(); if (this.HasNegativeCycle) { return; // Found a negative cycle. } } } }
public EdgeWeightedCycleChecker(EdgeWeightedDigraph graph) { this._visited = new Boolean[graph.VerticesCount]; this._onStack = new Boolean[graph.VerticesCount]; this._edgeTo = new Edge[graph.VerticesCount]; for (int i = 0; i < graph.VerticesCount; i++) { if (!this._visited[i]) { this.DFS(graph, i); } } }
private void FindNegativeCycle() // by finding a cycle in predecessor graph. { Int32 vertice = this._edgeTo.Length; EdgeWeightedDigraph graph = new EdgeWeightedDigraph(vertice); for (int i = 0; i < vertice; i++) { if (this._edgeTo[i] != null) { graph.AddEdge(this._edgeTo[i]); } } EdgeWeightedCycleChecker checker = EdgeWeightedCycleChecker.Create(graph); this._cycle = checker.GetCycle(); }
private void DFS(EdgeWeightedDigraph graph, Int32 vertice) { this._onStack[vertice] = true; this._visited[vertice] = true; foreach (Edge edge in graph.GetAdjacentVertices(vertice)) { Int32 targetVertice = edge.Target; // Short circuit if directed cycle found. if (this._cycle != null) { return; } // Found new vertex, so recur. if (!this._visited[targetVertice]) { this._edgeTo[targetVertice] = edge; this.DFS(graph, targetVertice); } // trace back directed cycle else if (this._onStack[targetVertice]) { this._cycle = new AST.Stack <Edge>(); Edge tempEdge = edge; while (tempEdge.Source != targetVertice) { this._cycle.Push(tempEdge); tempEdge = this._edgeTo[tempEdge.Source]; } this._cycle.Push(tempEdge); return; } } this._onStack[vertice] = false; }
public DijkstraShortestPathAlgorithm(EdgeWeightedDigraph graph, Int32 vertice) { foreach (Edge edge in graph.GetEdges()) { if (edge.Weight < 0) { throw new InvalidOperationException("Edge" + edge + " has negative weight."); } } this._distTo = new Double[graph.VerticesCount]; this._edgeTo = new Edge[graph.VerticesCount]; for (int i = 0; i < graph.VerticesCount; i++) { this._distTo[i] = Double.PositiveInfinity; } this._distTo[vertice] = 0.0; // Relax vertices in order of distance from vertice. this._crossingEdgesByWeight = new IndexedMinPQ <Double>(graph.VerticesCount) { { vertice, this._distTo[vertice] } }; while (!this._crossingEdgesByWeight.IsEmpty) { Int32 v = this._crossingEdgesByWeight.DeleteMin(); foreach (Edge edge in graph.GetAdjacentVertices(v)) { this.Relax(edge); } } }
public static EdgeWeightedCycleChecker Create(EdgeWeightedDigraph graph) { return(new EdgeWeightedCycleChecker(graph)); }