public void Evaluate(int SpreadMax) { if (FComp[0]) { alg = new FloydWarshallAllShortestPathAlgorithm <Message, MessageEdge>(FGraph[0], edge => 1); //alg.SetRootVertex(FRef[0]); alg.Finished += (sender, args) => { FDist.SliceCount = FVerts.SliceCount; FSucc.SliceCount = FVerts.SliceCount; for (int i = 0; i < FVerts.SliceCount; i++) { double result = -1; FSucc[i] = alg.TryGetDistance(FRef[0], FVerts[i], out result); FDist[i] = result; } }; if (FAsync[0]) { Task.Run(() => alg.Compute()); } else { alg.Compute(); } } FState[0] = alg?.State.ToString(); }
public void CalcCheapestPaths() { Func <TravelEdge, double> distanceFunc = new Func <TravelEdge, double>(edge => GetCost(edge.Source, edge.Target)); _fwAlgo = new FloydWarshallAllShortestPathAlgorithm <int, TravelEdge>(this.ToDirectedGrpah(), distanceFunc); _fwAlgo.Compute(); }
static void FloydWarshall(Dictionary <string, User> users) { var distances = new Dictionary <Edge <string>, double>(); var graph = MakeGraph(users); var edgeWeights = CalculateEdgecost(graph); var fw = new FloydWarshallAllShortestPathAlgorithm <string, Edge <string> >(graph, e => 1); var sw = new Stopwatch(); sw.Start(); fw.Compute(); sw.Stop(); Console.WriteLine("Ran for: " + sw.ElapsedMilliseconds + " ms"); foreach (var i in graph.Vertices.Take(10)) { foreach (var j in graph.Vertices) { Console.Write("{0} -> {1}:", i, j); IEnumerable <Edge <string> > path; if (fw.TryGetPath(i, j, out path)) { double cost = 0; foreach (var edge in path) { Console.Write("{0}, ", edge.Source); cost += distances[edge]; } Console.Write("{0} --- {1}", j, cost); } Console.WriteLine(); } } }
private static void CompareAlgorithms <TVertex, TEdge, TGraph>( [NotNull] AdjacencyGraph <TVertex, TEdge> graph, [NotNull, InstantHandle] Func <TEdge, double> getDistances, [NotNull, InstantHandle] Func <AdjacencyGraph <TVertex, TEdge>, Func <TEdge, double>, ShortestPathAlgorithmBase <TVertex, TEdge, TGraph> > shortestPathAlgorithmFactory) where TEdge : IEdge <TVertex> where TGraph : IVertexSet <TVertex> { // Compute all paths var algorithm = new FloydWarshallAllShortestPathAlgorithm <TVertex, TEdge>(graph, getDistances); algorithm.Compute(); TVertex[] vertices = graph.Vertices.ToArray(); foreach (TVertex source in vertices) { ShortestPathAlgorithmBase <TVertex, TEdge, TGraph> otherAlgorithm = shortestPathAlgorithmFactory(graph, getDistances); var predecessors = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); using (predecessors.Attach(otherAlgorithm)) otherAlgorithm.Compute(source); TryFunc <TVertex, IEnumerable <TEdge> > otherPaths = predecessors.TryGetPath; foreach (TVertex target in vertices) { if (source.Equals(target)) { continue; } bool pathExists = algorithm.TryGetPath(source, target, out IEnumerable <TEdge> floydPath); Assert.AreEqual(pathExists, otherPaths(target, out IEnumerable <TEdge> otherPath)); if (pathExists) { TEdge[] floydEdges = floydPath.ToArray(); CheckPath(source, target, floydEdges); TEdge[] otherEdges = otherPath.ToArray(); CheckPath(source, target, otherEdges); // All distances are usually 1 in this test, so it should at least // be the same number if (otherEdges.Length != floydEdges.Length) { Assert.Fail("Path do not have the same length."); } // Check path length are the same double floydLength = floydEdges.Sum(getDistances); double otherLength = otherEdges.Sum(getDistances); if (Math.Abs(floydLength - otherLength) > double.Epsilon) { Assert.Fail("Path do not have the same length."); } } } } }
/// <summary> /// Gets the intermediate events. /// </summary> /// <param name="initialState">The initial state.</param> /// <param name="finalState">The final state.</param> /// <returns></returns> public IEnumerable <Type> GetIntermediateEvents(string initialState, string finalState) { var fwAlgorithm = new FloydWarshallAllShortestPathAlgorithm <string, Transition <IDomainEvent <TEntity> > >(GetGraph, transition => _fsmTransitions[transition].Weight); fwAlgorithm.Compute(); IEnumerable <Transition <IDomainEvent <TEntity> > > transitions; fwAlgorithm.TryGetPath(initialState, finalState, out transitions); return(transitions.Select(transition => _fsmTransitions[transition].DomainEvent).ToList()); }
internal void LeastCostPaths() { FloydWarshallDistanceTester tester = new FloydWarshallDistanceTester( Distances, new FloydWarshallShortestPathDistanceTester() ); FloydWarshallAllShortestPathAlgorithm fw = new FloydWarshallAllShortestPathAlgorithm( VisitedGraph, tester ); fw.Compute(); fw.CheckConnectivityAndNegativeCycles(Distances); }
public static List <KeyValuePair <(string, 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 FloydWarshallAllShortestPathAlgorithm <string, TaggedEdge <string, string> >(graph, Weights); algorithm.Compute(); var results = new List <KeyValuePair <(string, string), double> >(); foreach (var v in graph.Vertices) { double distance = double.PositiveInfinity; algorithm.TryGetDistance(root, v, out distance); results.Add(new KeyValuePair <(string, string), double>((root, v), distance)); } return(results); }
public static List <KeyValuePair <(int, int), double> > Get(AdjacencyGraph <int, Edge <int> > graph, int root) { Func <Edge <int>, double> Weights = e => 1.0; var algorithm = new FloydWarshallAllShortestPathAlgorithm <int, Edge <int> >(graph, Weights); algorithm.Compute(); var results = new List <KeyValuePair <(int, int), double> >(); foreach (var v in graph.Vertices) { double distance = double.PositiveInfinity; algorithm.TryGetDistance(root, v, out distance); results.Add(new KeyValuePair <(int, int), double>((root, v), distance)); } return(results); }
public void Compute() { var distances = new Dictionary <Edge <char>, double>(); var g = CreateGraph(distances); var fw = new FloydWarshallAllShortestPathAlgorithm <char, Edge <char> >(g, e => distances[e]); fw.Compute(); fw.Dump(Console.Out); foreach (var i in g.Vertices) { foreach (var j in g.Vertices) { Console.Write("{0} -> {1}:", i, j); IEnumerable <Edge <char> > path; if (fw.TryGetPath(i, j, out path)) { double cost = 0; foreach (var edge in path) { Console.Write("{0}, ", edge.Source); cost += distances[edge]; } Console.Write("{0} --- {1}", j, cost); } Console.WriteLine(); } } { double distance; Assert.IsTrue(fw.TryGetDistance('A', 'A', out distance)); Assert.AreEqual(0, distance); Assert.IsTrue(fw.TryGetDistance('A', 'B', out distance)); Assert.AreEqual(6, distance); Assert.IsTrue(fw.TryGetDistance('A', 'C', out distance)); Assert.AreEqual(1, distance); Assert.IsTrue(fw.TryGetDistance('A', 'D', out distance)); Assert.AreEqual(4, distance); Assert.IsTrue(fw.TryGetDistance('A', 'E', out distance)); Assert.AreEqual(5, distance); } }
public static FloydWarshallAllShortestPathAlgorithm<int, UndirectedEdge<int>> ComputeShortestPaths(Dictionary<int, Node> nodes, IEnumerable<Edge> edges) { var graph = new AdjacencyGraph<int, UndirectedEdge<int>>(); foreach (int nodeId in nodes.Keys) { graph.AddVertex(nodeId); } foreach (Edge edge in edges) { graph.AddEdge(new UndirectedEdge<int>(edge.StartNodeId, edge.EndNodeId)); graph.AddEdge(new UndirectedEdge<int>(edge.EndNodeId, edge.StartNodeId)); } Func<UndirectedEdge<int>, double> edgeCost = e => GetEdgeCost(nodes, e); var pathFinder = new FloydWarshallAllShortestPathAlgorithm<int, UndirectedEdge<int>>(graph, edgeCost); pathFinder.Compute(); return pathFinder; }
public void TryGetPath() { const int vertex1 = 1; const int vertex2 = 2; const int vertex3 = 3; const int vertex4 = 4; var edge12 = new Edge <int>(vertex1, vertex2); var edge24 = new Edge <int>(vertex2, vertex4); var graph = new AdjacencyGraph <int, Edge <int> >(); graph.AddVerticesAndEdge(edge12); graph.AddVerticesAndEdge(edge24); graph.AddVertex(vertex3); var algorithm = new FloydWarshallAllShortestPathAlgorithm <int, Edge <int> >(graph, edge => 1.0); Assert.IsFalse(algorithm.TryGetPath(vertex1, vertex1, out _)); Assert.IsFalse(algorithm.TryGetPath(vertex1, vertex2, out _)); Assert.IsFalse(algorithm.TryGetPath(vertex1, vertex4, out _)); Assert.IsFalse(algorithm.TryGetPath(vertex1, vertex3, out _)); algorithm.Compute(); Assert.IsFalse(algorithm.TryGetPath(vertex1, vertex1, out _)); Assert.IsTrue(algorithm.TryGetPath(vertex1, vertex2, out IEnumerable <Edge <int> > path)); CollectionAssert.AreEqual( new[] { edge12 }, path); Assert.IsTrue(algorithm.TryGetPath(vertex1, vertex4, out path)); CollectionAssert.AreEqual( new[] { edge12, edge24 }, path); Assert.IsFalse(algorithm.TryGetPath(vertex1, vertex3, out _)); }
public void TryGetDistance() { const int vertex1 = 1; const int vertex2 = 2; const int vertex3 = 3; var graph = new AdjacencyGraph <int, Edge <int> >(); graph.AddVerticesAndEdge(new Edge <int>(vertex1, vertex2)); graph.AddVertex(vertex3); var algorithm = new FloydWarshallAllShortestPathAlgorithm <int, Edge <int> >(graph, edge => 1.0); Assert.IsFalse(algorithm.TryGetDistance(vertex1, vertex2, out _)); Assert.IsFalse(algorithm.TryGetDistance(vertex1, vertex3, out _)); algorithm.Compute(); Assert.IsTrue(algorithm.TryGetDistance(vertex1, vertex2, out double distance)); Assert.AreEqual(1, distance); Assert.IsFalse(algorithm.TryGetDistance(vertex1, vertex3, out _)); }
public void FloydWarshallSimpleGraph() { var distances = new Dictionary <Edge <char>, double>(); AdjacencyGraph <char, Edge <char> > graph = CreateGraph(distances); var algorithm = new FloydWarshallAllShortestPathAlgorithm <char, Edge <char> >(graph, e => distances[e]); algorithm.Compute(); Assert.IsTrue(algorithm.TryGetDistance('A', 'A', out double distance)); Assert.AreEqual(0, distance); Assert.IsTrue(algorithm.TryGetDistance('A', 'B', out distance)); Assert.AreEqual(6, distance); Assert.IsTrue(algorithm.TryGetDistance('A', 'C', out distance)); Assert.AreEqual(1, distance); Assert.IsTrue(algorithm.TryGetDistance('A', 'D', out distance)); Assert.AreEqual(4, distance); Assert.IsTrue(algorithm.TryGetDistance('A', 'E', out distance)); Assert.AreEqual(5, distance); }
public void FloydWarshall_Throws() { // 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 FloydWarshallAllShortestPathAlgorithm <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()); // 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 FloydWarshallAllShortestPathAlgorithm <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.Throws <NegativeCycleGraphException>(() => algorithm.Compute()); }
void Compare <TVertex, TEdge, TGraph>( AdjacencyGraph <TVertex, TEdge> g, Func <TEdge, double> distances, Func <AdjacencyGraph <TVertex, TEdge>, Func <TEdge, double>, ShortestPathAlgorithmBase <TVertex, TEdge, TGraph> > shortestPathAlgorithmFactory ) where TEdge : IEdge <TVertex> where TGraph : IVertexSet <TVertex> { // compute all paths var fw = new FloydWarshallAllShortestPathAlgorithm <TVertex, TEdge>(g, distances); fw.Compute(); var vertices = g.Vertices.ToArray(); foreach (var source in g.Vertices) { var dijkstra = shortestPathAlgorithmFactory(g, distances); // new DijkstraShortestPathAlgorithm<TVertex, TEdge>(g, distances); var predecessors = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); using (predecessors.Attach(dijkstra)) dijkstra.Compute(source); TryFunc <TVertex, IEnumerable <TEdge> > dijkstraPaths = predecessors.TryGetPath; foreach (var target in g.Vertices) { if (source.Equals(target)) { continue; } IEnumerable <TEdge> fwpath; IEnumerable <TEdge> dijpath; bool pathExists; Assert.AreEqual( pathExists = fw.TryGetPath(source, target, out fwpath), dijkstraPaths(target, out dijpath)); if (pathExists) { var fwedges = fwpath.ToArray(); CheckPath <TVertex, TEdge>(source, target, fwedges); var dijedges = dijpath.ToArray(); CheckPath <TVertex, TEdge>(source, target, dijedges); // all distances are usually 1 in this test, so it should at least // be the same number if (dijedges.Length != fwedges.Length) { DumpPaths <TVertex, TEdge>(source, target, fwedges, dijedges); Assert.Fail("path do not have the same length"); } // check path length are the same var fwlength = fwedges.Sum(distances); var dijlength = dijedges.Sum(distances); if (fwlength != dijlength) { DumpPaths <TVertex, TEdge>(source, target, fwedges, dijedges); Assert.Fail("path do not have the same length"); } } } } }
private void FindShortestPaths() { // Ungerichteten Graphen anlegen var graph = new AdjacencyGraph<int, UndirectedEdge<int>>(); foreach (int nodeId in Nodes.Keys) { graph.AddVertex(nodeId); } foreach (Edge edge in Edges) { graph.AddEdge(new UndirectedEdge<int>(edge.StartNodeId, edge.EndNodeId)); graph.AddEdge(new UndirectedEdge<int>(edge.EndNodeId, edge.StartNodeId)); } Func<UndirectedEdge<int>, double> edgeCost = e => GetEdgeCost(Nodes, e); PathFinder = new FloydWarshallAllShortestPathAlgorithm<int, UndirectedEdge<int>>(graph, edgeCost); PathFinder.Compute(); }