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."); } } } } }
protected static void TryGetDistance_Throws_Test <TVertex, TEdge, TGraph>( [NotNull] ShortestPathAlgorithmBase <TVertex, TEdge, TGraph> algorithm) where TVertex : class, new() where TEdge : IEdge <TVertex> where TGraph : IVertexSet <TVertex> { // ReSharper disable once AssignNullToNotNullAttribute Assert.Throws <ArgumentNullException>(() => algorithm.TryGetDistance(null, out _)); var vertex = new TVertex(); Assert.Throws <InvalidOperationException>(() => algorithm.TryGetDistance(vertex, out _)); }
protected static void TryGetDistance_Test <TEdge, TGraph>( [NotNull] ShortestPathAlgorithmBase <int, TEdge, TGraph> algorithm) where TEdge : IEdge <int> where TGraph : IVertexSet <int> { const int vertex1 = 1; algorithm.Compute(vertex1); Assert.IsTrue(algorithm.TryGetDistance(vertex1, out double distance)); Assert.AreEqual(algorithm.Distances[vertex1], distance); const int vertex2 = 2; Assert.IsFalse(algorithm.TryGetDistance(vertex2, out _)); }