public static TryFunc <TVertex, IEnumerable <TEdge> > ShortestPathsBellmanFord <TVertex, TEdge>( #if !NET20 this #endif IVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph, Func <TEdge, double> edgeWeights, TVertex source ) where TEdge : IEdge <TVertex> { Contract.Requires(visitedGraph != null); Contract.Requires(edgeWeights != null); Contract.Requires(source != null); var algorithm = new BellmanFordShortestPathAlgorithm <TVertex, TEdge>(visitedGraph, edgeWeights); var predecessorRecorder = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); using (predecessorRecorder.Attach(algorithm)) algorithm.Compute(source); var predecessors = predecessorRecorder.VertexPredecessors; return(delegate(TVertex v, out IEnumerable <TEdge> edges) { return EdgeExtensions.TryGetPath(predecessors, v, out edges); }); }
public void SetRootVertex_Throws() { var graph = new AdjacencyGraph <TestVertex, Edge <TestVertex> >(); var algorithm = new BellmanFordShortestPathAlgorithm <TestVertex, Edge <TestVertex> >(graph, _ => 1.0); SetRootVertex_Throws_Test(algorithm); }
public void ClearRootVertex() { var graph = new AdjacencyGraph <int, Edge <int> >(); var algorithm = new BellmanFordShortestPathAlgorithm <int, Edge <int> >(graph, _ => 1.0); ClearRootVertex_Test(algorithm); }
public void TryGetDistance_Throws() { var graph = new AdjacencyGraph <TestVertex, Edge <TestVertex> >(); var algorithm = new BellmanFordShortestPathAlgorithm <TestVertex, Edge <TestVertex> >(graph, edge => 1.0); TryGetDistance_Throws_Test(algorithm); }
internal static Dictionary <string, double> Ancestor(Graph weightedDirectedGraph) { var tempGraph = new Graph(); var resultDictionary = new Dictionary <string, double>(); //Create negative weighted directed graph tempGraph.AddVertexRange(weightedDirectedGraph.Vertices); tempGraph.AddEdgeRange(weightedDirectedGraph.Edges.Select(x => new Edge(x.Name, x.Source, x.Target, -x.Weight))); //Solve shortest path of Top -> vertex var algorithm = new BellmanFordShortestPathAlgorithm <string, Edge>(tempGraph, e => e.Weight); var pred = new VertexPredecessorRecorderObserver <string, Edge>(); pred.Attach(algorithm); foreach (var vertex in tempGraph.Vertices) { algorithm.Compute("Top"); IEnumerable <Edge> path; pred.TryGetPath(vertex, out path); if (path != null) { resultDictionary[vertex] = -path.Sum(a => a.Weight); } } return(resultDictionary); }
public void TryGetDistance() { var graph = new AdjacencyGraph <int, Edge <int> >(); graph.AddVertex(1); var algorithm = new BellmanFordShortestPathAlgorithm <int, Edge <int> >(graph, edge => 1.0); TryGetDistance_Test(algorithm); }
public static IDictionary <string, double> Get(AdjacencyGraph <string, TaggedEdge <string, string> > graph, string root) { Func <TaggedEdge <string, string>, double> Weights = e => double.Parse(e.Tag); var algorithm = new BellmanFordShortestPathAlgorithm <string, TaggedEdge <string, string> >(graph, Weights); algorithm.Compute(root); return(algorithm.Distances); }
public void ComputeWithRoot() { var graph = new AdjacencyGraph <int, Edge <int> >(); graph.AddVertex(0); var algorithm = new BellmanFordShortestPathAlgorithm <int, Edge <int> >(graph, _ => 1.0); ComputeWithRoot_Test(algorithm); }
public static IDictionary <int, double> Get(AdjacencyGraph <int, Edge <int> > graph, int root) { Func <Edge <int>, double> Weights = e => 1.0; var algorithm = new BellmanFordShortestPathAlgorithm <int, Edge <int> >(graph, Weights); algorithm.Compute(root); return(algorithm.Distances); }
public void GetVertexColor_Throws() { var graph = new AdjacencyGraph <int, Edge <int> >(); graph.AddVertex(0); var algorithm = new BellmanFordShortestPathAlgorithm <int, Edge <int> >(graph, edge => 1.0); algorithm.Compute(0); // ReSharper disable once ReturnValueOfPureMethodIsNotUsed Assert.Throws <VertexNotFoundException>(() => algorithm.GetVertexColor(1)); }
public void GetVertexColor() { var graph = new AdjacencyGraph <int, Edge <int> >(); graph.AddVerticesAndEdge(new Edge <int>(1, 2)); var algorithm = new BellmanFordShortestPathAlgorithm <int, Edge <int> >(graph, _ => 1.0); algorithm.Compute(1); Assert.AreEqual(GraphColor.Black, algorithm.GetVertexColor(1)); Assert.AreEqual(GraphColor.Black, algorithm.GetVertexColor(2)); }
public void Test_PathTo() { BellmanFordShortestPathAlgorithm alg = new BellmanFordShortestPathAlgorithm(this.CreateDigraph(), 0); AssertUtilities.Sequence(new Edge[4] { new Edge(0, 1, .5), new Edge(1, 5, .3), new Edge(5, 6, .5), new Edge(6, 4, .1) }, alg.PathTo(4)); }
public void Constructor() { Func <Edge <int>, double> Weights = _ => 1.0; var graph = new AdjacencyGraph <int, Edge <int> >(); var algorithm = new BellmanFordShortestPathAlgorithm <int, Edge <int> >(graph, Weights); AssertAlgorithmProperties(algorithm, graph, Weights); algorithm = new BellmanFordShortestPathAlgorithm <int, Edge <int> >(graph, Weights, DistanceRelaxers.CriticalDistance); AssertAlgorithmProperties(algorithm, graph, Weights, DistanceRelaxers.CriticalDistance); algorithm = new BellmanFordShortestPathAlgorithm <int, Edge <int> >(null, graph, Weights, DistanceRelaxers.CriticalDistance); AssertAlgorithmProperties(algorithm, graph, Weights, DistanceRelaxers.CriticalDistance); #region Local function void AssertAlgorithmProperties <TVertex, TEdge>( BellmanFordShortestPathAlgorithm <TVertex, TEdge> algo, IVertexAndEdgeListGraph <TVertex, TEdge> g, Func <TEdge, double> eWeights = null, IDistanceRelaxer relaxer = null) where TEdge : IEdge <TVertex> { AssertAlgorithmState(algo, g); Assert.IsNull(algo.VerticesColors); Assert.IsFalse(algo.FoundNegativeCycle); if (eWeights is null) { Assert.IsNotNull(algo.Weights); } else { Assert.AreSame(eWeights, algo.Weights); } CollectionAssert.IsEmpty(algo.GetDistances()); if (relaxer is null) { Assert.IsNotNull(algo.DistanceRelaxer); } else { Assert.AreSame(relaxer, algo.DistanceRelaxer); } } #endregion }
public static BellmanFordShortestPathAlgorithm <T, Edge <T> > CreateAlgorithmAndMaybeDoComputation <T>( [NotNull] ContractScenario <T> scenario) { var graph = new AdjacencyGraph <T, Edge <T> >(); graph.AddVerticesAndEdgeRange(scenario.EdgesInGraph.Select(e => new Edge <T>(e.Source, e.Target))); graph.AddVertexRange(scenario.SingleVerticesInGraph); double Weights(Edge <T> e) => 1.0; var algorithm = new BellmanFordShortestPathAlgorithm <T, Edge <T> >(graph, Weights); if (scenario.DoComputation) { algorithm.Compute(scenario.Root); } return(algorithm); }
//public void FindPath(string @from = "START", string @to = "END") //{ // Func<Edge<string>, double> edgeCost = AlgorithmExtensions.GetIndexer(EdgeCost); // // Positive or negative weights // TryFunc<string, System.Collections.Generic.IEnumerable<Edge<string>>> tryGetPath = Graph.ShortestPathsBellmanFord(edgeCost, @from); // IEnumerable<Edge<string>> path; // if (tryGetPath(@to, out path)) // { // Console.Write("Path found from {0} to {1}: {0}", @from, @to); // foreach (var e in path) { Console.Write(" > {0}", e.Target); } // Console.WriteLine(); // } // else { Console.WriteLine("No path found from {0} to {1}."); } //} public double GetETA(string start = "A") { Func <Edge <Vertex>, double> edgeCost = e => this.edgeCostList[e]; // Bellman algorithm works with either positive or negative weights BellmanFordShortestPathAlgorithm <Vertex, Edge <Vertex> > pathCalc = new BellmanFordShortestPathAlgorithm <Vertex, Edge <Vertex> >(this.graph, edgeCost); Vertex source = nodeMap[start]; Vertex target = nodeMap["Z"]; pathCalc.Compute(source); var distances = pathCalc.Distances; var distanceToTarget = 0 - distances[target]; return(distanceToTarget); }
private static void Verify <TVertex, TEdge>( [NotNull] BellmanFordShortestPathAlgorithm <TVertex, TEdge> algorithm, [NotNull] VertexPredecessorRecorderObserver <TVertex, TEdge> predecessors) where TEdge : IEdge <TVertex> { // Verify the result foreach (TVertex vertex in algorithm.VisitedGraph.Vertices) { if (!predecessors.VerticesPredecessors.TryGetValue(vertex, out TEdge predecessor)) { continue; } if (predecessor.Source.Equals(vertex)) { continue; } Assert.AreEqual( algorithm.TryGetDistance(vertex, out double currentDistance), algorithm.TryGetDistance(predecessor.Source, out double predecessorDistance)); Assert.GreaterOrEqual(currentDistance, predecessorDistance); } }
private static void RunBellmanFordAndCheck <TVertex, TEdge>( [NotNull] IVertexAndEdgeListGraph <TVertex, TEdge> graph, [NotNull] TVertex root) where TEdge : IEdge <TVertex> { var distances = new Dictionary <TEdge, double>(); foreach (TEdge edge in graph.Edges) { distances[edge] = graph.OutDegree(edge.Source) + 1; } var algorithm = new BellmanFordShortestPathAlgorithm <TVertex, TEdge>( graph, e => distances[e]); algorithm.InitializeVertex += vertex => { Assert.AreEqual(GraphColor.White, algorithm.VerticesColors[vertex]); }; var predecessors = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); using (predecessors.Attach(algorithm)) algorithm.Compute(root); Assert.AreEqual(graph.VertexCount, algorithm.VerticesColors.Count); foreach (TVertex vertex in graph.Vertices) { Assert.AreEqual(GraphColor.Black, algorithm.VerticesColors[vertex]); } Assert.IsFalse(algorithm.FoundNegativeCycle); CollectionAssert.IsNotEmpty(algorithm.GetDistances()); Assert.AreEqual(graph.VertexCount, algorithm.GetDistances().Count()); Verify(algorithm, predecessors); }
public void BellmanFord_NegativeCycle() { // Without negative cycle var edge12 = new Edge <int>(1, 2); var edge23 = new Edge <int>(2, 3); var edge34 = new Edge <int>(3, 4); var negativeWeightGraph = new AdjacencyGraph <int, Edge <int> >(); negativeWeightGraph.AddVerticesAndEdgeRange(new[] { edge12, edge23, edge34 }); var algorithm = new BellmanFordShortestPathAlgorithm <int, Edge <int> >( negativeWeightGraph, e => { if (e == edge12) { return(12.0); } if (e == edge23) { return(-23.0); } if (e == edge34) { return(-34.0); } return(1.0); }); Assert.DoesNotThrow(() => algorithm.Compute(1)); Assert.IsFalse(algorithm.FoundNegativeCycle); // With negative cycle var edge41 = new Edge <int>(4, 1); var negativeCycleGraph = new AdjacencyGraph <int, Edge <int> >(); negativeCycleGraph.AddVerticesAndEdgeRange(new[] { edge12, edge23, edge34, edge41 }); algorithm = new BellmanFordShortestPathAlgorithm <int, Edge <int> >( negativeCycleGraph, e => { if (e == edge12) { return(12.0); } if (e == edge23) { return(-23.0); } if (e == edge34) { return(-34.0); } if (e == edge41) { return(41.0); } return(1.0); }); Assert.DoesNotThrow(() => algorithm.Compute(1)); Assert.IsTrue(algorithm.FoundNegativeCycle); }
public void Test_NotHasPathTo() { BellmanFordShortestPathAlgorithm alg = new BellmanFordShortestPathAlgorithm(this.CreateDigraph(), 0); Assert.False(alg.HasPathTo(7)); }
public void Test_DistanceTo() { BellmanFordShortestPathAlgorithm alg = new BellmanFordShortestPathAlgorithm(this.CreateDigraph(), 0); Assert.Equal(1.4, Math.Round(alg.DistanceTo(4), 1)); }