public Paths(Vertex source, HashMap <Vertex, Edge <Vertex> > edgeTo) { Source = source; this.edgeTo = edgeTo; }
/// <summary> /// Solves the single-source shortest path problem in O(E*V) time for a graph without any negative cycles, or in O(V+E) time if it is a DAG. /// </summary> public static Paths <V> BellmanFord <V>(DiGraph <V> graph, V source) { if (graph == null || source == null) { throw new ArgumentNullException(); } if (!graph.Contains(source)) { throw new ArgumentException(); } var distTo = new HashMap <V, Double>(); var edgeTo = new HashMap <V, Edge <V> >(); bool Relax(Edge <V> e) { var(v, w) = (e.from, e.to); var weight = new Double(e.weight); if (distTo[v] > distTo[w] + weight) { distTo[w] = distTo[v] + weight; edgeTo[w] = e; return(true); } return(false); } foreach (var v in graph.Vertices()) { distTo[v] = Double.MaxValue; } distTo[source] = new Double(0); // The Bellman Ford procedure involves relaxing every edge V times. // However, for a DAG we can delegate to a simpler algorithm that runs in linear time try { var vertices = TopologicalSort(graph); foreach (var v in vertices) { foreach (var e in graph.Edges(v)) { Relax(e); } } } catch (InvalidOperationException) { // Graph is not a DAG var N = graph.Size(); foreach (var i in Enumerable.Range(1, N)) { foreach (var e in graph.Edges()) { var relaxed = Relax(e); if (i == N && relaxed) { throw new InvalidOperationException("Negative cycle detected"); } } } } return(new Paths <V>(source, edgeTo)); }