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()); }
public TravelPath GetPath(int start, int dest) { IEnumerable <TravelEdge> path = new List <TravelEdge>(); if (_fwAlgo.TryGetPath(start, dest, out path)) { return(ConvertToPath(path, start)); } else { return(null); } }
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 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 IList <Cell> GetPathBetweenCells( Cell source, Cell target, FloydWarshallAllShortestPathAlgorithm <Cell, Edge <Cell> > pathAlgorithm) { if ((source == null) || (target == null) || (source == target)) { return(null); } IEnumerable <Edge <Cell> > edges; //tries to return "walkable" path between cells if ((this.cellGraph == null) || (pathAlgorithm == null) || (pathAlgorithm.State != ComputationState.Finished) || !pathAlgorithm.TryGetPath(source, target, out edges)) { return(null); } return(edges.Select(edge => edge.Target).ToList()); }
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"); } } } } }