Ejemplo n.º 1
0
        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 _));
        }