Beispiel #1
0
        protected override IList <P> FindShortestPathHook(
            V startVertex,
            V endVertex,
            int maxNumberOfPaths
            )
        {
            var       yenAdaptee = new YenShortestPathsAlgorithm <string>(graphAdaptee, startVertex.VertexId, endVertex.VertexId, maxNumberOfPaths);
            IList <P> paths      = new System.Collections.Generic.List <P>();
            IEnumerable <YenShortestPathsAlgorithm <string> .SortedPath> adapteePaths = yenAdaptee.Execute();

            foreach (YenShortestPathsAlgorithm <string> .SortedPath adapteePath in adapteePaths)
            {
                IEnumerable <EquatableTaggedEdge <string, double> > adapteeEdges = adapteePath.AsEnumerable();
                IList <E> edges = new System.Collections.Generic.List <E>();
                double    wei   = 0;
                foreach (EquatableTaggedEdge <string, double> adapteeEdge in adapteeEdges)
                {
                    wei += adapteeEdge.Tag;
                    E edge = this.GetOriginalEdgeInstance(adapteeEdge);
                    edges.Add(
                        edge
                        );
                }
                W totalWeight = base.CreateInstanceWithTotalWeight(wei, edges);
                paths.Add(base.CreatePath(totalWeight, edges));
            }
            return(new ReadOnlyCollection <P>(paths));
        }
Beispiel #2
0
        private void YenNormalCaseTestBody(YenShortestPathsAlgorithm <char> yen,
                                           AdjacencyGraph <char, TaggedEquatableEdge <char, double> > input)
        {
            /*  generate simple graph
             *  like this https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
             *  but with directed edgesinput.Graph
             */
            var result = yen.Execute().ToList();

            /*
             * Expecting to get 3 paths:
             * 1. 1-3-4-5
             * 2. 1-2-4-5
             * 3. 1-2-3-4-5
             * Consistently checking the result
             */
            Assert.AreEqual(3, result.Count);
            // 1.
            Assert.AreEqual(result[0].ToArray()[0], input.Edges.ToArray()[1]);
            Assert.AreEqual(result[0].ToArray()[1], input.Edges.ToArray()[5]);
            Assert.AreEqual(result[0].ToArray()[2], input.Edges.ToArray()[7]);
            // 2.
            Assert.AreEqual(result[1].ToArray()[0], input.Edges.ToArray()[0]);
            Assert.AreEqual(result[1].ToArray()[1], input.Edges.ToArray()[4]);
            Assert.AreEqual(result[1].ToArray()[2], input.Edges.ToArray()[7]);
            // 3.
            Assert.AreEqual(result[2].ToArray()[0], input.Edges.ToArray()[0]);
            Assert.AreEqual(result[2].ToArray()[1], input.Edges.ToArray()[3]);
            Assert.AreEqual(result[2].ToArray()[2], input.Edges.ToArray()[5]);
            Assert.AreEqual(result[2].ToArray()[3], input.Edges.ToArray()[7]);
        }
Beispiel #3
0
        public void YenNormalCaseTest()
        {
            /* generate simple graph
             * like this https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
             * but with directed edgesinput.Graph
             */
            var input  = GenerateNormalInput();
            var yen    = new YenShortestPathsAlgorithm <char> (input, '1', '5', 10);
            var result = yen.Execute().ToList();

            /*
             * Expecting to get 3 paths:
             * 1. 1-3-4-5
             * 2. 1-2-4-5
             * 3. 1-2-3-4-5
             * Consistently checking the result
             */
            Assert.AreEqual(3, result.Count);
            // 1.
            Assert.AreEqual(result[0].ToArray()[0], input.Edges.ToArray()[1]);
            Assert.AreEqual(result[0].ToArray()[1], input.Edges.ToArray()[5]);
            Assert.AreEqual(result[0].ToArray()[2], input.Edges.ToArray()[7]);
            // 2.
            Assert.AreEqual(result[1].ToArray()[0], input.Edges.ToArray()[0]);
            Assert.AreEqual(result[1].ToArray()[1], input.Edges.ToArray()[4]);
            Assert.AreEqual(result[1].ToArray()[2], input.Edges.ToArray()[7]);
            // 3.
            Assert.AreEqual(result[2].ToArray()[0], input.Edges.ToArray()[0]);
            Assert.AreEqual(result[2].ToArray()[1], input.Edges.ToArray()[3]);
            Assert.AreEqual(result[2].ToArray()[2], input.Edges.ToArray()[5]);
            Assert.AreEqual(result[2].ToArray()[3], input.Edges.ToArray()[7]);
        }
Beispiel #4
0
        public static (YenShortestPathsAlgorithm <string> .SortedPath, string) Get(AdjacencyGraph <string, EquatableTaggedEdge <string, double> > graph, string root, string target)
        {
            int k         = int.MaxValue;
            var algorithm = new YenShortestPathsAlgorithm <string>(graph, root, target, k);

            YenShortestPathsAlgorithm <string> .SortedPath shortest = new YenShortestPathsAlgorithm <string> .SortedPath();

            var shortestDistance = double.MaxValue;

            try
            {
                var paths = algorithm.Execute().ToArray();
                foreach (var path in paths)
                {
                    double sum = 0;
                    foreach (var e in path)
                    {
                        sum += e.Tag;
                    }
                    if (sum < shortestDistance)
                    {
                        shortest         = path;
                        shortestDistance = sum;
                    }
                }
                return(shortest, null);
            }
            catch (System.Exception ex)
            {
                return(shortest, ex.Message);
            }
        }
        public void YenZeroCaseTest()
        {
            AdjacencyGraph <char, TaggedEquatableEdge <char, double> > graph = new AdjacencyGraph <char, TaggedEquatableEdge <char, double> >(true);

            var algorithm = new YenShortestPathsAlgorithm <char>(graph, '1', '5', 10);

            Assert.Throws <KeyNotFoundException>(() => algorithm.Execute());
        }
Beispiel #6
0
        public void EmptyGraph()
        {
            var graph = new AdjacencyGraph <char, EquatableTaggedEdge <char, double> >(true);

            var algorithm = new YenShortestPathsAlgorithm <char>(graph, '1', '5', 10);

            // ReSharper disable once ReturnValueOfPureMethodIsNotUsed
            Assert.Throws <NoPathFoundException>(() => algorithm.Execute());
        }
        public void Test()
        {
            var graph = new AdjacencyGraph <string, EquatableTaggedEdge <string, double> >(false);

            graph.AddVertexRange(new List <string> {
                "A", "B", "C", "D"
            });
            graph.AddEdge(new EquatableTaggedEdge <string, double>("A", "B", 5));
            graph.AddEdge(new EquatableTaggedEdge <string, double>("A", "C", 6));
            graph.AddEdge(new EquatableTaggedEdge <string, double>("B", "C", 7));
            graph.AddEdge(new EquatableTaggedEdge <string, double>("B", "D", 8));
            graph.AddEdge(new EquatableTaggedEdge <string, double>("C", "D", 9));
            var yen = new YenShortestPathsAlgorithm <string>(graph, "A", "D", 5);
            // The three paths *should* be:
            // A -> B -> D (weight: 13 = 5 + 8)
            // A -> C -> D (weight: 15 = 6 + 9)
            // A -> B -> C -> D (weight: 21 = 5 + 7 + 9)
            var actualPaths = yen.Execute().ToList();

            //foreach(var path in actualPaths)
            //{
            //    var edges = path.ToList();
            //    Console.WriteLine();
            //    Console.Write(edges[0].Source);
            //    for(int i=0; i<edges.Count; i++) {
            //        Console.Write(" -> " +edges[i].Target);
            //    }
            //}
            // Output from above loops:
            //  A -> B -> D
            //  A -> C -> D
            // The last path was missing (i.e. A -> B -> C -> D) for QuickGraph 3.7.3
            Assert.AreEqual(3, actualPaths.Count); // Failure for QuickGraph 3.7.3 : Expected: 3 But was:  2
            // but when running the code with the fork for QuikGraph 1.0.0, then it works

            var path1 = actualPaths[0];
            var path2 = actualPaths[1];
            var path3 = actualPaths[2];

            Assert.AreEqual("A", path1.ElementAt(0).Source);
            Assert.AreEqual("B", path1.ElementAt(0).Target);
            Assert.AreEqual("B", path1.ElementAt(1).Source);
            Assert.AreEqual("D", path1.ElementAt(1).Target);

            Assert.AreEqual("A", path2.ElementAt(0).Source);
            Assert.AreEqual("C", path2.ElementAt(0).Target);
            Assert.AreEqual("C", path2.ElementAt(1).Source);
            Assert.AreEqual("D", path2.ElementAt(1).Target);

            Assert.AreEqual("A", path3.ElementAt(0).Source);
            Assert.AreEqual("B", path3.ElementAt(0).Target);
            Assert.AreEqual("B", path3.ElementAt(1).Source);
            Assert.AreEqual("C", path3.ElementAt(1).Target);
            Assert.AreEqual("C", path3.ElementAt(2).Source);
            Assert.AreEqual("D", path3.ElementAt(2).Target);
        }
        public void YenOneVertexCaseTest()
        {
            var graph = new AdjacencyGraph <char, TaggedEquatableEdge <char, double> >(true);

            graph.AddVertexRange("1");

            var algorithm = new YenShortestPathsAlgorithm <char>(graph, '1', '1', 10);

            Assert.Throws <NoPathFoundException>(() => algorithm.Execute());
        }
Beispiel #9
0
        public static (YenShortestPathsAlgorithm <string> .SortedPath[], string) GetAll(AdjacencyGraph <string, EquatableTaggedEdge <string, double> > graph, string root, string target)
        {
            int k         = int.MaxValue;
            var algorithm = new YenShortestPathsAlgorithm <string>(graph, root, target, k);

            try
            {
                var paths = algorithm.Execute().ToArray();
                return(paths, null);
            }
            catch (System.Exception ex)
            {
                return(null, ex.Message);
            }
        }
Beispiel #10
0
        public void OneVertexGraph()
        {
            var graph = new AdjacencyGraph <char, EquatableTaggedEdge <char, double> >(true);

            graph.AddVertexRange("1");

            // ReSharper disable ReturnValueOfPureMethodIsNotUsed
            var algorithm = new YenShortestPathsAlgorithm <char>(graph, '1', '1', 10);

            Assert.Throws <NoPathFoundException>(() => algorithm.Execute());

            algorithm = new YenShortestPathsAlgorithm <char>(graph, '1', '2', 10);
            Assert.Throws <NoPathFoundException>(() => algorithm.Execute());
            // ReSharper restore ReturnValueOfPureMethodIsNotUsed
        }
 public void YenZeroCaseTest()
 {
   var graph = new AdjacencyGraph<char, TaggedEquatableEdge<char, double>>(true);
   var yen = new YenShortestPathsAlgorithm<char>(graph, '1', '5', 10);
   var exeptionWas = false;
   try
   {
     yen.Execute();
   }
   catch (Exception e)
   {
     Assert.AreEqual(true, e is System.Collections.Generic.KeyNotFoundException);
     exeptionWas = true;
   }
   Assert.AreEqual(exeptionWas, true);
 }
 public void YenOneVertexCaseTest()
 {
   var graph = new AdjacencyGraph<char, TaggedEquatableEdge<char, double>>(true);
   graph.AddVertexRange("1");
   var yen = new YenShortestPathsAlgorithm<char>(graph, '1', '1', 10);
   var exeptionWas = false;
   try
   {
     yen.Execute();
   }
   catch (Exception e)
   {
     Assert.AreEqual(true, e is NoPathFoundException);
     exeptionWas = true;
   }
   Assert.AreEqual(exeptionWas, true);
 }
Beispiel #13
0
        public void SortedPathEnumeration()
        {
            var edges = new[]
            {
                new EquatableTaggedEdge <int, double>(1, 2, 1.0),
                new EquatableTaggedEdge <int, double>(2, 3, 1.0),
                new EquatableTaggedEdge <int, double>(3, 4, 1.0)
            };

            var path = new YenShortestPathsAlgorithm <int> .SortedPath(edges);

            CollectionAssert.AreEqual(edges, path);

            CollectionAssert.IsEmpty(
                new YenShortestPathsAlgorithm <int> .SortedPath(
                    Enumerable.Empty <EquatableTaggedEdge <int, double> >()));
        }
Beispiel #14
0
        public void YenZeroCaseTest()
        {
            var graph       = new AdjacencyGraph <char, TaggedEquatableEdge <char, double> >(true);
            var yen         = new YenShortestPathsAlgorithm <char>(graph, '1', '5', 10);
            var exeptionWas = false;

            try
            {
                yen.Execute();
            }
            catch (Exception e)
            {
                Assert.AreEqual(true, e is System.Collections.Generic.KeyNotFoundException);
                exeptionWas = true;
            }
            Assert.AreEqual(exeptionWas, true);
        }
Beispiel #15
0
        public void YenOneVertexCaseTest()
        {
            var graph = new AdjacencyGraph <char, TaggedEquatableEdge <char, double> >(true);

            graph.AddVertexRange("1");
            var yen         = new YenShortestPathsAlgorithm <char>(graph, '1', '1', 10);
            var exeptionWas = false;

            try
            {
                yen.Execute();
            }
            catch (Exception e)
            {
                Assert.AreEqual(true, e is NoPathFoundException);
                exeptionWas = true;
            }
            Assert.AreEqual(exeptionWas, true);
        }
Beispiel #16
0
        public void YenNormalCaseTest()
        {
            var input = GenerateNormalInput();

            // default weight function and default filter function case
            var yen = new YenShortestPathsAlgorithm <char>(input, '1', '5', 10);

            YenNormalCaseTestBody(yen, input);

            // custom weight function and default filter function case
            yen = new YenShortestPathsAlgorithm <char>(input, '1', '5', 10, e => e.Tag);
            YenNormalCaseTestBody(yen, input);

            // default weight function and custom filter function case
            yen = new YenShortestPathsAlgorithm <char>(input, '1', '5', 10, null, e => e);
            YenNormalCaseTestBody(yen, input);

            // custom weight function and custom filter function case
            yen = new YenShortestPathsAlgorithm <char>(input, '1', '5', 10, e => e.Tag, e => e);
            YenNormalCaseTestBody(yen, input);
        }
Beispiel #17
0
        public void YenLoopCaseTest()
        {
            var graph = new AdjacencyGraph <char, TaggedEquatableEdge <char, double> >(true);

            graph.AddVertexRange("1");
            var yen = new YenShortestPathsAlgorithm <char>(graph, '1', '1', 10);

            graph.AddEdge(new TaggedEquatableEdge <char, double>('1', '1', 7));
            var exeptionWas = true;

            try
            {
                var result = yen.Execute().ToList();
            }
            catch (Exception e)
            {
                Assert.AreEqual(true, e is InstanceNotFoundException);
                exeptionWas = true;
            }
            Assert.AreEqual(exeptionWas, true);
        }
Beispiel #18
0
        public void GraphWithMultiplePaths()
        {
            var graph = new AdjacencyGraph <string, EquatableTaggedEdge <string, double> >(false);

            graph.AddVertexRange(new[] { "A", "B", "C", "D" });
            var edges = new[]
            {
                new EquatableTaggedEdge <string, double>("A", "B", 5),
                new EquatableTaggedEdge <string, double>("A", "C", 6),
                new EquatableTaggedEdge <string, double>("B", "C", 7),
                new EquatableTaggedEdge <string, double>("B", "D", 8),
                new EquatableTaggedEdge <string, double>("C", "D", 9)
            };

            graph.AddEdgeRange(edges);

            var algorithm = new YenShortestPathsAlgorithm <string>(graph, "A", "D", 5);

            YenShortestPathsAlgorithm <string> .SortedPath[] paths = algorithm.Execute().ToArray();

            // Expecting to get 3 paths:
            // 1 => A-B-D
            // 2 => A-C-D
            // 3 => A-B-C-D
            // Consistently checking the result
            Assert.AreEqual(3, paths.Length);
            // 1
            EquatableTaggedEdge <string, double>[] path0 = paths[0].ToArray();
            Assert.AreEqual(path0[0], edges[0]);
            Assert.AreEqual(path0[1], edges[3]);
            // 2
            EquatableTaggedEdge <string, double>[] path1 = paths[1].ToArray();
            Assert.AreEqual(path1[0], edges[1]);
            Assert.AreEqual(path1[1], edges[4]);
            // 3
            EquatableTaggedEdge <string, double>[] path2 = paths[2].ToArray();
            Assert.AreEqual(path2[0], edges[0]);
            Assert.AreEqual(path2[1], edges[2]);
            Assert.AreEqual(path2[2], edges[4]);
        }
Beispiel #19
0
        public void GraphWithCycle()
        {
            var graph = new AdjacencyGraph <char, EquatableTaggedEdge <char, double> >(true);

            graph.AddVertexRange("12345");
            var edges = new[]
            {
                new EquatableTaggedEdge <char, double>('1', '2', 1.0),
                new EquatableTaggedEdge <char, double>('1', '3', 12.0),
                new EquatableTaggedEdge <char, double>('1', '4', 0.5),
                new EquatableTaggedEdge <char, double>('2', '3', 3.0),
                new EquatableTaggedEdge <char, double>('2', '4', 2.0),
                new EquatableTaggedEdge <char, double>('3', '5', 1.0),
                new EquatableTaggedEdge <char, double>('5', '2', 6.0)
            };

            graph.AddEdgeRange(edges);

            var algorithm = new YenShortestPathsAlgorithm <char>(graph, '1', '5', 10);

            YenShortestPathsAlgorithm <char> .SortedPath[] paths = algorithm.Execute().ToArray();

            // Expecting to get 2 paths:
            // 1 => 1-2-3-5
            // 2 => 1-3-5
            // Consistently checking the result
            Assert.AreEqual(2, paths.Length);
            // 1
            EquatableTaggedEdge <char, double>[] path0 = paths[0].ToArray();
            Assert.AreEqual(path0[0], edges[0]);
            Assert.AreEqual(path0[1], edges[3]);
            Assert.AreEqual(path0[2], edges[5]);
            // 2
            EquatableTaggedEdge <char, double>[] path1 = paths[1].ToArray();
            Assert.AreEqual(path1[0], edges[1]);
            Assert.AreEqual(path1[1], edges[5]);
        }
Beispiel #20
0
        public void SortedPathHashCode()
        {
            var edges = new[]
            {
                new EquatableTaggedEdge <int, double>(1, 2, 1.0),
                new EquatableTaggedEdge <int, double>(2, 3, 1.0),
                new EquatableTaggedEdge <int, double>(3, 4, 1.0)
            };
            var path1 = new YenShortestPathsAlgorithm <int> .SortedPath(edges);

            var path2 = new YenShortestPathsAlgorithm <int> .SortedPath(edges);

            var path3 = new YenShortestPathsAlgorithm <int> .SortedPath(new[]
            {
                new EquatableTaggedEdge <int, double>(1, 2, 1.0),
                new EquatableTaggedEdge <int, double>(2, 3, 1.0),
                new EquatableTaggedEdge <int, double>(3, 4, 1.0)
            });

            Assert.AreEqual(path1.GetHashCode(), path1.GetHashCode());
            Assert.AreNotEqual(path1.GetHashCode(), path2.GetHashCode());
            Assert.AreNotEqual(path1.GetHashCode(), path3.GetHashCode());
            Assert.AreNotEqual(path2.GetHashCode(), path3.GetHashCode());
        }
Beispiel #21
0
        public void MultipleRunMethods()
        {
            AdjacencyGraph <char, EquatableTaggedEdge <char, double> > graph = GenerateGraph(
                out EquatableTaggedEdge <char, double>[] graphEdges);

            // Default weight function and default filter function case
            var algorithm = new YenShortestPathsAlgorithm <char>(graph, '1', '5', 10);

            RunYenAndCheck(algorithm);

            // Custom weight function and default filter function case
            algorithm = new YenShortestPathsAlgorithm <char>(graph, '1', '5', 10, e => e.Tag);
            RunYenAndCheck(algorithm);

            // Default weight function and custom filter function case
            algorithm = new YenShortestPathsAlgorithm <char>(graph, '1', '5', 10, null, e => e);
            RunYenAndCheck(algorithm);

            // Custom weight function and custom filter function case
            algorithm = new YenShortestPathsAlgorithm <char>(graph, '1', '5', 10, e => e.Tag, e => e);
            RunYenAndCheck(algorithm);

            #region Local functions

            AdjacencyGraph <char, EquatableTaggedEdge <char, double> > GenerateGraph(
                out EquatableTaggedEdge <char, double>[] edges)
            {
                var g = new AdjacencyGraph <char, EquatableTaggedEdge <char, double> >(true);

                g.AddVertexRange("123456");
                edges = new[]
                {
                    new EquatableTaggedEdge <char, double>('1', '2', 7),
                    new EquatableTaggedEdge <char, double>('1', '3', 9),
                    new EquatableTaggedEdge <char, double>('1', '6', 14),
                    new EquatableTaggedEdge <char, double>('2', '3', 10),
                    new EquatableTaggedEdge <char, double>('2', '4', 15),
                    new EquatableTaggedEdge <char, double>('3', '4', 11),
                    new EquatableTaggedEdge <char, double>('3', '6', 2),
                    new EquatableTaggedEdge <char, double>('4', '5', 6),
                    new EquatableTaggedEdge <char, double>('5', '6', 9)
                };
                g.AddEdgeRange(edges);

                return(g);
            }

            void RunYenAndCheck(YenShortestPathsAlgorithm <char> yen)
            {
                // Generate simple graph
                // like this https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
                // but with directed edges input graph
                YenShortestPathsAlgorithm <char> .SortedPath[] paths = yen.Execute().ToArray();

                // Expecting to get 3 paths:
                // 1 => 1-3-4-5
                // 2 => 1-2-4-5
                // 3 => 1-2-3-4-5
                // Consistently checking the result
                Assert.AreEqual(3, paths.Length);
                // 1
                EquatableTaggedEdge <char, double>[] path0 = paths[0].ToArray();
                Assert.AreEqual(path0[0], graphEdges[1]);
                Assert.AreEqual(path0[1], graphEdges[5]);
                Assert.AreEqual(path0[2], graphEdges[7]);
                // 2
                EquatableTaggedEdge <char, double>[] path1 = paths[1].ToArray();
                Assert.AreEqual(path1[0], graphEdges[0]);
                Assert.AreEqual(path1[1], graphEdges[4]);
                Assert.AreEqual(path1[2], graphEdges[7]);
                // 3
                EquatableTaggedEdge <char, double>[] path2 = paths[2].ToArray();
                Assert.AreEqual(path2[0], graphEdges[0]);
                Assert.AreEqual(path2[1], graphEdges[3]);
                Assert.AreEqual(path2[2], graphEdges[5]);
                Assert.AreEqual(path2[3], graphEdges[7]);
            }

            #endregion
        }
Beispiel #22
0
        public void GraphWithMultiplePaths_KShortest()
        {
            var graph = new AdjacencyGraph <char, EquatableTaggedEdge <char, double> >(false);

            graph.AddVertexRange("CDEFGH");
            var edges = new[]
            {
                new EquatableTaggedEdge <char, double>('C', 'D', 3),
                new EquatableTaggedEdge <char, double>('C', 'E', 2),
                new EquatableTaggedEdge <char, double>('D', 'F', 4),
                new EquatableTaggedEdge <char, double>('E', 'D', 1),
                new EquatableTaggedEdge <char, double>('E', 'F', 2),
                new EquatableTaggedEdge <char, double>('E', 'G', 3),
                new EquatableTaggedEdge <char, double>('F', 'G', 2),
                new EquatableTaggedEdge <char, double>('F', 'H', 1),
                new EquatableTaggedEdge <char, double>('G', 'H', 2)
            };

            graph.AddEdgeRange(edges);

            // K = 5
            var algorithmK5 = new YenShortestPathsAlgorithm <char>(graph, 'C', 'H', 5);

            YenShortestPathsAlgorithm <char> .SortedPath[] paths = algorithmK5.Execute().ToArray();

            // Expecting to get 5 paths:
            // 1 => C-E-F-H
            // 2 => C-E-G-H
            // 3 => C-E-F-G-H
            // 4 => C-E-D-F-H
            // 5 => C-D-F-H
            // Consistently checking the result
            Assert.AreEqual(5, paths.Length);
            CheckFiveFirstPaths(paths);


            // K = 50
            var algorithmK50 = new YenShortestPathsAlgorithm <char>(graph, 'C', 'H', 50);

            paths = algorithmK50.Execute().ToArray();

            // Expecting to get 7 paths:
            // 1 => C-E-F-H
            // 2 => C-E-G-H
            // 3 => C-E-F-G-H
            // 4 => C-E-D-F-H
            // 5 => C-D-F-H
            // 6 => C-E-D-F-G-H
            // 7 => C-D-F-G-H
            // Consistently checking the result
            Assert.AreEqual(7, paths.Length);
            CheckFiveFirstPaths(paths);
            // 6
            EquatableTaggedEdge <char, double>[] path5 = paths[5].ToArray();
            Assert.AreEqual(path5[0], edges[1]);    // C-E
            Assert.AreEqual(path5[1], edges[3]);    // E-D
            Assert.AreEqual(path5[2], edges[2]);    // D-F
            Assert.AreEqual(path5[3], edges[6]);    // F-G
            Assert.AreEqual(path5[4], edges[8]);    // G-H
            // 7
            EquatableTaggedEdge <char, double>[] path6 = paths[6].ToArray();
            Assert.AreEqual(path6[0], edges[0]);    // C-D
            Assert.AreEqual(path6[1], edges[2]);    // D-F
            Assert.AreEqual(path6[2], edges[6]);    // F-G
            Assert.AreEqual(path6[3], edges[8]);    // G-H

            #region Local function

            void CheckFiveFirstPaths(YenShortestPathsAlgorithm <char> .SortedPath[] ps)
            {
                // 1
                EquatableTaggedEdge <char, double>[] path0 = ps[0].ToArray();
                Assert.AreEqual(path0[0], edges[1]);    // C-E
                Assert.AreEqual(path0[1], edges[4]);    // E-F
                Assert.AreEqual(path0[2], edges[7]);    // F-H
                // 2
                EquatableTaggedEdge <char, double>[] path1 = ps[1].ToArray();
                Assert.AreEqual(path1[0], edges[1]);    // C-E
                Assert.AreEqual(path1[1], edges[5]);    // E-G
                Assert.AreEqual(path1[2], edges[8]);    // G-H
                // 3
                EquatableTaggedEdge <char, double>[] path2 = ps[2].ToArray();
                Assert.AreEqual(path2[0], edges[1]);    // C-E
                Assert.AreEqual(path2[1], edges[4]);    // E-F
                Assert.AreEqual(path2[2], edges[6]);    // F-G
                Assert.AreEqual(path2[3], edges[8]);    // G-H
                // 4
                EquatableTaggedEdge <char, double>[] path3 = ps[3].ToArray();
                Assert.AreEqual(path3[0], edges[1]);    // C-E
                Assert.AreEqual(path3[1], edges[3]);    // E-D
                Assert.AreEqual(path3[2], edges[2]);    // D-F
                Assert.AreEqual(path3[3], edges[7]);    // F-H
                // 5
                EquatableTaggedEdge <char, double>[] path4 = ps[4].ToArray();
                Assert.AreEqual(path4[0], edges[0]);    // C-D
                Assert.AreEqual(path4[1], edges[2]);    // D-F
                Assert.AreEqual(path4[2], edges[7]);    // F-H
            }

            #endregion
        }
    private void YenNormalCaseTestBody(YenShortestPathsAlgorithm<char> yen,
      AdjacencyGraph<char, TaggedEquatableEdge<char, double>> input)
    {
      /*  generate simple graph
          like this https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
          but with directed edgesinput.Graph
      */
      var result = yen.Execute().ToList();

      /*
      Expecting to get 3 paths:
      1. 1-3-4-5
      2. 1-2-4-5
      3. 1-2-3-4-5
      Consistently checking the result
      */
      Assert.AreEqual(3, result.Count);
      // 1.
      Assert.AreEqual(result[0].ToArray()[0], input.Edges.ToArray()[1]);
      Assert.AreEqual(result[0].ToArray()[1], input.Edges.ToArray()[5]);
      Assert.AreEqual(result[0].ToArray()[2], input.Edges.ToArray()[7]);
      // 2.
      Assert.AreEqual(result[1].ToArray()[0], input.Edges.ToArray()[0]);
      Assert.AreEqual(result[1].ToArray()[1], input.Edges.ToArray()[4]);
      Assert.AreEqual(result[1].ToArray()[2], input.Edges.ToArray()[7]);
      // 3.
      Assert.AreEqual(result[2].ToArray()[0], input.Edges.ToArray()[0]);
      Assert.AreEqual(result[2].ToArray()[1], input.Edges.ToArray()[3]);
      Assert.AreEqual(result[2].ToArray()[2], input.Edges.ToArray()[5]);
      Assert.AreEqual(result[2].ToArray()[3], input.Edges.ToArray()[7]);
    }
    public void YenNormalCaseTest()
    {
      var input = GenerateNormalInput();

      // default weight function and default filter function case
      var yen = new YenShortestPathsAlgorithm<char>(input, '1', '5', 10);
      YenNormalCaseTestBody(yen, input);

      // custom weight function and default filter function case
      yen = new YenShortestPathsAlgorithm<char>(input, '1', '5', 10, e => e.Tag);
      YenNormalCaseTestBody(yen, input);

      // default weight function and custom filter function case
      yen = new YenShortestPathsAlgorithm<char>(input, '1', '5', 10, null, e => e);
      YenNormalCaseTestBody(yen, input);

      // custom weight function and custom filter function case
      yen = new YenShortestPathsAlgorithm<char>(input, '1', '5', 10, e => e.Tag, e => e);
      YenNormalCaseTestBody(yen, input);
    }
        public void YenNormalCaseTest()
        {
            AdjacencyGraph <char, TaggedEquatableEdge <char, double> > graph = GenerateGraph();

            // Default weight function and default filter function case
            var algorithm = new YenShortestPathsAlgorithm <char>(graph, '1', '5', 10);

            RunYenAndCheck(algorithm, graph);

            // Custom weight function and default filter function case
            algorithm = new YenShortestPathsAlgorithm <char>(graph, '1', '5', 10, e => e.Tag);
            RunYenAndCheck(algorithm, graph);

            // Default weight function and custom filter function case
            algorithm = new YenShortestPathsAlgorithm <char>(graph, '1', '5', 10, null, e => e);
            RunYenAndCheck(algorithm, graph);

            // Custom weight function and custom filter function case
            algorithm = new YenShortestPathsAlgorithm <char>(graph, '1', '5', 10, e => e.Tag, e => e);
            RunYenAndCheck(algorithm, graph);

            #region Local functions

            AdjacencyGraph <char, TaggedEquatableEdge <char, double> > GenerateGraph()
            {
                var g = new AdjacencyGraph <char, TaggedEquatableEdge <char, double> >(true);

                g.AddVertexRange("123456");
                g.AddEdge(new TaggedEquatableEdge <char, double>('1', '2', 7));  // 0
                g.AddEdge(new TaggedEquatableEdge <char, double>('1', '3', 9));  // 1
                g.AddEdge(new TaggedEquatableEdge <char, double>('1', '6', 14)); // 2
                g.AddEdge(new TaggedEquatableEdge <char, double>('2', '3', 10)); // 3
                g.AddEdge(new TaggedEquatableEdge <char, double>('2', '4', 15)); // 4
                g.AddEdge(new TaggedEquatableEdge <char, double>('3', '4', 11)); // 5
                g.AddEdge(new TaggedEquatableEdge <char, double>('3', '6', 2));  // 6
                g.AddEdge(new TaggedEquatableEdge <char, double>('4', '5', 6));  // 7
                g.AddEdge(new TaggedEquatableEdge <char, double>('5', '6', 9));  // 8

                return(g);
            }

            void RunYenAndCheck(YenShortestPathsAlgorithm <char> yen, AdjacencyGraph <char, TaggedEquatableEdge <char, double> > g)
            {
                // Generate simple graph
                // like this https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
                // but with directed edges input graph
                YenShortestPathsAlgorithm <char> .SortedPath[] paths = yen.Execute().ToArray();

                // Expecting to get 3 paths:
                // 1 => 1-3-4-5
                // 2 => 1-2-4-5
                // 3 => 1-2-3-4-5
                // Consistently checking the result
                Assert.AreEqual(3, paths.Length);
                // 1
                Assert.AreEqual(paths[0].ToArray()[0], g.Edges.ToArray()[1]);
                Assert.AreEqual(paths[0].ToArray()[1], g.Edges.ToArray()[5]);
                Assert.AreEqual(paths[0].ToArray()[2], g.Edges.ToArray()[7]);
                // 2
                Assert.AreEqual(paths[1].ToArray()[0], g.Edges.ToArray()[0]);
                Assert.AreEqual(paths[1].ToArray()[1], g.Edges.ToArray()[4]);
                Assert.AreEqual(paths[1].ToArray()[2], g.Edges.ToArray()[7]);
                // 3
                Assert.AreEqual(paths[2].ToArray()[0], g.Edges.ToArray()[0]);
                Assert.AreEqual(paths[2].ToArray()[1], g.Edges.ToArray()[3]);
                Assert.AreEqual(paths[2].ToArray()[2], g.Edges.ToArray()[5]);
                Assert.AreEqual(paths[2].ToArray()[3], g.Edges.ToArray()[7]);
            }

            #endregion
        }