コード例 #1
0
        public void FindShortestPathForSimpleUndirectedGraphUsingDijkstraAlgorithm()
        {
            var graph = new UndirectedGraph<object, Edge<object>>(true);
            object v1 = "vertex1";
            object v2 = "vertex2";
            object v3 = "vertex3";
            var e1 = new Edge<object>(v1, v2);
            var e2 = new Edge<object>(v2, v3);
            var e3 = new Edge<object>(v3, v1);
            graph.AddVertex(v1);
            graph.AddVertex(v2);
            graph.AddVertex(v3);
            graph.AddEdge(e1);
            graph.AddEdge(e2);
            graph.AddEdge(e3);

            var algorithm = new UndirectedDijkstraShortestPathAlgorithm<object, Edge<object>>(graph, edge => (double)1);
            var observer = new UndirectedVertexPredecessorRecorderObserver<object, Edge<object>>();
            using (observer.Attach(algorithm))
            {
                algorithm.Compute(v1);
            }

            IEnumerable<Edge<object>> path;
            observer.TryGetPath(v3, out path);

            foreach (var edge in path)
            {
                Console.WriteLine(edge);
            }
        }
コード例 #2
0
        /// <summary>
        /// Computes the minimum spanning tree using Prim's algorithm.
        /// Prim's algorithm is simply implemented by calling Dijkstra shortest path.
        /// </summary>
        /// <typeparam name="TVertex">type of the vertices</typeparam>
        /// <typeparam name="TEdge">type of the edges</typeparam>
        /// <param name="visitedGraph"></param>
        /// <param name="weights"></param>
        /// <returns></returns>
        public static IEnumerable <TEdge> MinimumSpanningTreePrim <TVertex, TEdge>(
#if !NET20
            this
#endif
            IUndirectedGraph <TVertex, TEdge> visitedGraph,
            Func <TEdge, double> weights)
            where TEdge : IEdge <TVertex>
        {
            Contract.Requires(visitedGraph != null);
            Contract.Requires(weights != null);

            if (visitedGraph.VertexCount == 0)
            {
                return(new TEdge[0]);
            }

            var distanceRelaxer = PrimRelaxer.Instance;
            var dijkstra        = new UndirectedDijkstraShortestPathAlgorithm <TVertex, TEdge>(visitedGraph, weights, distanceRelaxer);
            var edgeRecorder    = new UndirectedVertexPredecessorRecorderObserver <TVertex, TEdge>();

            using (edgeRecorder.Attach(dijkstra))
                dijkstra.Compute();

            return(edgeRecorder.VertexPredecessors.Values);
        }
コード例 #3
0
        public void UndirectedDijkstraSimpleGraph()
        {
            var    undirectedGraph = new UndirectedGraph <object, Edge <object> >(true);
            object v1 = "vertex1";
            object v2 = "vertex2";
            object v3 = "vertex3";
            var    e1 = new Edge <object>(v1, v2);
            var    e2 = new Edge <object>(v2, v3);
            var    e3 = new Edge <object>(v3, v1);

            undirectedGraph.AddVertex(v1);
            undirectedGraph.AddVertex(v2);
            undirectedGraph.AddVertex(v3);
            undirectedGraph.AddEdge(e1);
            undirectedGraph.AddEdge(e2);
            undirectedGraph.AddEdge(e3);

            var algorithm = new UndirectedDijkstraShortestPathAlgorithm <object, Edge <object> >(
                undirectedGraph,
                edge => 1.0);
            var observer = new UndirectedVertexPredecessorRecorderObserver <object, Edge <object> >();

            using (observer.Attach(algorithm))
                algorithm.Compute(v1);

            Assert.IsTrue(observer.TryGetPath(v3, out _));
        }
コード例 #4
0
        public static TryFunc <TVertex, IEnumerable <TEdge> > ShortestPathsDijkstra <TVertex, TEdge>(
#if !NET20
            this
#endif
            IUndirectedGraph <TVertex, TEdge> visitedGraph,
            Func <TEdge, double> edgeWeights,
            TVertex source
            )
            where TEdge : IEdge <TVertex>
        {
            Contract.Requires(visitedGraph != null);
            Contract.Requires(edgeWeights != null);
            Contract.Requires(source != null);

            var algorithm           = new UndirectedDijkstraShortestPathAlgorithm <TVertex, TEdge>(visitedGraph, edgeWeights);
            var predecessorRecorder = new UndirectedVertexPredecessorRecorderObserver <TVertex, TEdge>();

            using (predecessorRecorder.Attach(algorithm))
                algorithm.Compute(source);

            var predecessors = predecessorRecorder.VertexPredecessors;

            return(delegate(TVertex v, out IEnumerable <TEdge> edges)
            {
                return EdgeExtensions.TryGetPath(predecessors, v, out edges);
            });
        }
コード例 #5
0
        public void Repro42450()
        {
            var    ug = new UndirectedGraph <object, Edge <object> >(true);
            object v1 = "vertex1";
            object v2 = "vertex2";
            object v3 = "vertex3";
            var    e1 = new Edge <object>(v1, v2);
            var    e2 = new Edge <object>(v2, v3);
            var    e3 = new Edge <object>(v3, v1);

            ug.AddVertex(v1);
            ug.AddVertex(v2);
            ug.AddVertex(v3);
            ug.AddEdge(e1);
            ug.AddEdge(e2);
            ug.AddEdge(e3);

            var udspa =
                new UndirectedDijkstraShortestPathAlgorithm <object, QuickGraph.Edge <object> >(ug, edge => (double)1);
            var observer =
                new UndirectedVertexPredecessorRecorderObserver <object, Edge <object> >();

            using (observer.Attach(udspa))
                udspa.Compute(v1);
            IEnumerable <QuickGraph.Edge <object> > path;

            observer.TryGetPath(v3, out path);
        }
コード例 #6
0
ファイル: Graph.cs プロジェクト: joey94/NavigatorFinal
        public List <UndirEdge> FindPath(string start, string end)
        {
            var dijkstra = new UndirectedDijkstraShortestPathAlgorithm <string, UndirEdge>(this, edge => 1);
            var observer = new UndirectedVertexPredecessorRecorderObserver <string, UndirEdge>();

            observer.Attach(dijkstra);

            var nodeCheckX = Vertices.FirstOrDefault(node => node == start);
            var nodeCheckY = Vertices.FirstOrDefault(node => node == end);

            if (nodeCheckX != null && nodeCheckY != null)
            {
                dijkstra.Compute(start);
                IEnumerable <UndirEdge> path = null;
                try {
                    observer.TryGetPath(end, out path);
                } catch {
                }

                return(path.ToList());
            }
            else
            {
                return(null);
            }
        }
コード例 #7
0
ファイル: TravelGraph.cs プロジェクト: limonana/AI_Course
        public TravelPath ShortestPath(int sourcePlace, int targetPlace)
        {
            var algo = new UndirectedBreadthFirstSearchAlgorithm <int, TravelEdge>(this);

            algo.SetRootVertex(sourcePlace);
            var predecessors = new UndirectedVertexPredecessorRecorderObserver <int, TravelEdge>();

            predecessors.Attach(algo);

            algo.Compute();

            List <TravelEdge> path = new List <TravelEdge>();
            var place = targetPlace;

            //there is no way to get to the target
            if (!predecessors.VertexPredecessors.ContainsKey(place))
            {
                return(null);
            }

            while (place != sourcePlace)
            {
                var edge = predecessors.VertexPredecessors[place];
                path.Insert(0, edge);
                place = edge.getAnotherPlace(place);
            }
            return(ConvertToPath(path, sourcePlace));
        }
コード例 #8
0
        public void FindShortestPathForSimpleUndirectedGraphUsingDijkstraAlgorithm()
        {
            var    graph = new UndirectedGraph <object, Edge <object> >(true);
            object v1    = "vertex1";
            object v2    = "vertex2";
            object v3    = "vertex3";
            var    e1    = new Edge <object>(v1, v2);
            var    e2    = new Edge <object>(v2, v3);
            var    e3    = new Edge <object>(v3, v1);

            graph.AddVertex(v1);
            graph.AddVertex(v2);
            graph.AddVertex(v3);
            graph.AddEdge(e1);
            graph.AddEdge(e2);
            graph.AddEdge(e3);

            var algorithm = new UndirectedDijkstraShortestPathAlgorithm <object, Edge <object> >(graph, edge => (double)1);
            var observer  = new UndirectedVertexPredecessorRecorderObserver <object, Edge <object> >();

            using (observer.Attach(algorithm))
            {
                algorithm.Compute(v1);
            }

            IEnumerable <Edge <object> > path;

            observer.TryGetPath(v3, out path);

            foreach (var edge in path)
            {
                Console.WriteLine(edge);
            }
        }
        public void TryGetPath()
        {
            {
                var recorder = new UndirectedVertexPredecessorRecorderObserver <int, Edge <int> >();

                var graph = new UndirectedGraph <int, Edge <int> >();

                var dfs = new UndirectedDepthFirstSearchAlgorithm <int, Edge <int> >(graph);
                using (recorder.Attach(dfs))
                {
                    dfs.Compute();

                    // Vertex not in the graph
                    Assert.IsFalse(recorder.TryGetPath(2, out _));
                }
            }

            {
                var recorder = new UndirectedVertexPredecessorRecorderObserver <int, Edge <int> >();

                var graph = new UndirectedGraph <int, Edge <int> >();
                graph.AddVertexRange(new[] { 1, 2 });

                var dfs = new UndirectedDepthFirstSearchAlgorithm <int, Edge <int> >(graph);
                using (recorder.Attach(dfs))
                {
                    dfs.Compute();

                    Assert.IsFalse(recorder.TryGetPath(2, out _));
                }
            }

            {
                var recorder = new UndirectedVertexPredecessorRecorderObserver <int, Edge <int> >();

                var edge12 = new Edge <int>(1, 2);
                var edge14 = new Edge <int>(1, 4);
                var edge31 = new Edge <int>(3, 1);
                var edge33 = new Edge <int>(3, 3);
                var edge34 = new Edge <int>(3, 4);
                var edge42 = new Edge <int>(4, 2);
                var graph  = new UndirectedGraph <int, Edge <int> >();
                graph.AddVerticesAndEdgeRange(new[]
                {
                    edge12, edge14, edge31, edge33, edge34, edge42
                });

                var dfs = new UndirectedDepthFirstSearchAlgorithm <int, Edge <int> >(graph);
                using (recorder.Attach(dfs))
                {
                    dfs.Compute();

                    Assert.IsTrue(recorder.TryGetPath(4, out IEnumerable <Edge <int> > path));
                    CollectionAssert.AreEqual(new[] { edge12, edge42 }, path);
                }
            }
        }
コード例 #10
0
        public static IDictionary <int, Edge <int> > Get(UndirectedGraph <int, Edge <int> > g)
        {
            var dfs      = new UndirectedDepthFirstSearchAlgorithm <int, Edge <int> >(g);
            var recorder = new UndirectedVertexPredecessorRecorderObserver <int, Edge <int> >();

            using (recorder.Attach(dfs))
            {
                dfs.Compute();
                return(recorder.VerticesPredecessors);
            }
        }
コード例 #11
0
        public static IEnumerable <TaggedEdge <string, string> > GetPath(UndirectedGraph <string, TaggedEdge <string, string> > g, string v)
        {
            var dfs      = new UndirectedDepthFirstSearchAlgorithm <string, TaggedEdge <string, string> >(g);
            var recorder = new UndirectedVertexPredecessorRecorderObserver <string, TaggedEdge <string, string> >();

            using (recorder.Attach(dfs))
            {
                dfs.Compute();
                recorder.TryGetPath(v, out var path);
                return(path);
            }
        }
        private static IList <Edge> ComputeShortestPath(Edge branch, IEnumerable <Edge> delaunyEdges, Matrix volumeIndexToNormalizedVolumeCoordinates)
        {
            var graph = new UndirectedGraph <Vector3, Edge <Vector3> >();

            foreach (var delaunyEdge in delaunyEdges)
            {
                graph.AddVerticesAndEdge(new Edge <Vector3>(delaunyEdge.P1, delaunyEdge.P2));
            }

            var dijkstraShortestPathAlgorithm = new UndirectedDijkstraShortestPathAlgorithm <Vector3, Edge <Vector3> >(graph, edge => CalculateEdgeWeights(edge, volumeIndexToNormalizedVolumeCoordinates));
            var visitor = new UndirectedVertexPredecessorRecorderObserver <Vector3, Edge <Vector3> >();

            using (visitor.Attach(dijkstraShortestPathAlgorithm))
            {
                dijkstraShortestPathAlgorithm.Compute(branch.P1);
            }

            IEnumerable <Edge <Vector3> > shortestPath;

            visitor.TryGetPath(branch.P2, out shortestPath);

            var edgeList         = (from edge in shortestPath select new Edge {
                P1 = edge.Source, P2 = edge.Target
            }).ToList();
            var orientedEdgeList = new List <Edge>();

            var edgeListP1 = edgeList[0].P1;
            var edgeListP2 = edgeList[0].P2;

            orientedEdgeList.Add(!edgeList[0].P1.Equals(branch.P1)
                                      ? new Edge {
                P1 = edgeListP2, P2 = edgeListP1
            }
                                      : new Edge {
                P1 = edgeListP1, P2 = edgeListP2
            });

            for (int i = 1; i < edgeList.Count; i++)
            {
                edgeListP1 = edgeList[i].P1;
                edgeListP2 = edgeList[i].P2;

                orientedEdgeList.Add(!edgeList[i].P1.Equals(orientedEdgeList[i - 1].P2)
                                          ? new Edge {
                    P1 = edgeListP2, P2 = edgeListP1
                }
                                          : new Edge {
                    P1 = edgeListP1, P2 = edgeListP2
                });
            }

            return(orientedEdgeList);
        }
        public void Constructor()
        {
            var recorder = new UndirectedVertexPredecessorRecorderObserver <int, Edge <int> >();

            CollectionAssert.IsEmpty(recorder.VerticesPredecessors);

            var predecessors = new Dictionary <int, Edge <int> >();

            recorder = new UndirectedVertexPredecessorRecorderObserver <int, Edge <int> >(predecessors);
            Assert.AreSame(predecessors, recorder.VerticesPredecessors);

            predecessors = new Dictionary <int, Edge <int> >
            {
                [1] = new Edge <int>(2, 1)
            };
            recorder = new UndirectedVertexPredecessorRecorderObserver <int, Edge <int> >(predecessors);
            Assert.AreSame(predecessors, recorder.VerticesPredecessors);
        }
コード例 #14
0
        private static void RunUndirectedDijkstraAndCheck <TVertex, TEdge>([NotNull] IUndirectedGraph <TVertex, TEdge> graph, [NotNull] TVertex root)
            where TEdge : IEdge <TVertex>
        {
            var distances = new Dictionary <TEdge, double>();

            foreach (TEdge edge in graph.Edges)
            {
                distances[edge] = graph.AdjacentDegree(edge.Source) + 1;
            }

            var algorithm    = new UndirectedDijkstraShortestPathAlgorithm <TVertex, TEdge>(graph, e => distances[e]);
            var predecessors = new UndirectedVertexPredecessorRecorderObserver <TVertex, TEdge>();

            using (predecessors.Attach(algorithm))
                algorithm.Compute(root);

            Verify(algorithm, predecessors);
        }
コード例 #15
0
        private void UndirectedDijkstra <TVertex, TEdge>(IUndirectedGraph <TVertex, TEdge> g, TVertex root)
            where TEdge : IEdge <TVertex>
        {
            var distances = new Dictionary <TEdge, double>();

            foreach (var e in g.Edges)
            {
                distances[e] = g.AdjacentDegree(e.Source) + 1;
            }

            var algo = new UndirectedDijkstraShortestPathAlgorithm <TVertex, TEdge>(
                g,
                e => distances[e]
                );
            var predecessors = new UndirectedVertexPredecessorRecorderObserver <TVertex, TEdge>();

            using (predecessors.Attach(algo))
                algo.Compute(root);

            Verify(algo, predecessors);
        }
コード例 #16
0
 private static void Verify <TVertex, TEdge>(
     [NotNull] UndirectedDijkstraShortestPathAlgorithm <TVertex, TEdge> algorithm,
     [NotNull] UndirectedVertexPredecessorRecorderObserver <TVertex, TEdge> predecessors)
     where TEdge : IEdge <TVertex>
 {
     // Verify the result
     foreach (TVertex vertex in algorithm.VisitedGraph.Vertices)
     {
         if (!predecessors.VerticesPredecessors.TryGetValue(vertex, out TEdge predecessor))
         {
             continue;
         }
         if (predecessor.Source.Equals(vertex))
         {
             continue;
         }
         Assert.AreEqual(
             algorithm.TryGetDistance(vertex, out double currentDistance),
             algorithm.TryGetDistance(predecessor.Source, out double predecessorDistance));
         Assert.GreaterOrEqual(currentDistance, predecessorDistance);
     }
 }
コード例 #17
0
ファイル: BoardFutures.cs プロジェクト: vfridell/Diplomacy
        private static IEnumerable <UnitMove> GetConvoyMoves(Board board)
        {
            List <UnitMove> convoyMoves      = new List <UnitMove>();
            var             currentConvoyMap = board.GetCurrentConvoyMap();

            foreach (MapNode source in currentConvoyMap.Vertices.Where(mn => mn.Territory.TerritoryType == TerritoryType.Coast))
            {
                Unit unit;
                if (!board.OccupiedMapNodes.TryGetValue(source.ConvoyParent(), out unit))
                {
                    continue;
                }
                if (currentConvoyMap.AdjacentDegree(source) > 0)
                {
                    //var alg = new HoffmanPavleyRankedShortestPathAlgorithm<MapNode, UndirectedEdge<MapNode>>( currentConvoyMap, n => 1);
                    var alg = new UndirectedDijkstraShortestPathAlgorithm <MapNode, UndirectedEdge <MapNode> >(currentConvoyMap, n => 1);
                    //alg.SetGoalVertex(target);
                    var predecessorObserver = new UndirectedVertexPredecessorRecorderObserver <MapNode, UndirectedEdge <MapNode> >();
                    alg.SetRootVertex(source);
                    using (var foo = predecessorObserver.Attach(alg))
                    {
                        alg.Compute();
                    }
                    foreach (MapNode target in currentConvoyMap.Vertices.Where(mn => mn.Territory.TerritoryType == TerritoryType.Coast))
                    {
                        IEnumerable <UndirectedEdge <MapNode> > rawPath;
                        if (!predecessorObserver.TryGetPath(target, out rawPath))
                        {
                            continue;
                        }
                        List <MapNode> edgeList   = MakeConvoyPathList(source, target, rawPath);
                        var            convoyMove = new UnitMove(unit, new UndirectedEdge <MapNode>(source.ConvoyParent(), target.ConvoyParent()), edgeList);
                        convoyMoves.Add(convoyMove);
                    }
                }
            }

            return(convoyMoves);
        }
コード例 #18
0
 private static void Verify <TVertex, TEdge>(
     [NotNull] UndirectedDijkstraShortestPathAlgorithm <TVertex, TEdge> algorithm,
     [NotNull] UndirectedVertexPredecessorRecorderObserver <TVertex, TEdge> predecessors)
     where TEdge : IEdge <TVertex>
 {
     // Verify the result
     foreach (TVertex vertex in algorithm.VisitedGraph.Vertices)
     {
         if (!predecessors.VertexPredecessors.TryGetValue(vertex, out TEdge predecessor))
         {
             continue;
         }
         if (predecessor.Source.Equals(vertex))
         {
             continue;
         }
         bool found = algorithm.TryGetDistance(vertex, out double vd);
         Assert.AreEqual(found, algorithm.TryGetDistance(predecessor.Source, out double vp));
         if (found)
         {
             Assert.AreEqual(vd, vp + 1);
         }
     }
 }
コード例 #19
0
 private static void Verify <TVertex, TEdge>(
     UndirectedDijkstraShortestPathAlgorithm <TVertex, TEdge> algo,
     UndirectedVertexPredecessorRecorderObserver <TVertex, TEdge> predecessors)
     where TEdge : IEdge <TVertex>
 {
     // let's verify the result
     foreach (var v in algo.VisitedGraph.Vertices)
     {
         TEdge predecessor;
         if (!predecessors.VertexPredecessors.TryGetValue(v, out predecessor))
         {
             continue;
         }
         if (predecessor.Source.Equals(v))
         {
             continue;
         }
         double vd, vp;
         bool   found;
         Assert.Equal(found = algo.TryGetDistance(v, out vd), algo.TryGetDistance(predecessor.Source, out vp));
         //if (found)
         //    Assert.Equal(vd, vp + 1, 8);
     }
 }
コード例 #20
0
        private static void RunUndirectedDijkstraAndCheck <TVertex, TEdge>([NotNull] IUndirectedGraph <TVertex, TEdge> graph, [NotNull] TVertex root)
            where TEdge : IEdge <TVertex>
        {
            var distances = new Dictionary <TEdge, double>();

            foreach (TEdge edge in graph.Edges)
            {
                distances[edge] = graph.AdjacentDegree(edge.Source) + 1;
            }

            var algorithm    = new UndirectedDijkstraShortestPathAlgorithm <TVertex, TEdge>(graph, e => distances[e]);
            var predecessors = new UndirectedVertexPredecessorRecorderObserver <TVertex, TEdge>();

            using (predecessors.Attach(algorithm))
                algorithm.Compute(root);

            algorithm.InitializeVertex += vertex =>
            {
                Assert.AreEqual(GraphColor.White, algorithm.VerticesColors[vertex]);
            };

            algorithm.DiscoverVertex += vertex =>
            {
                Assert.AreEqual(GraphColor.Gray, algorithm.VerticesColors[vertex]);
            };

            algorithm.FinishVertex += vertex =>
            {
                Assert.AreEqual(GraphColor.Black, algorithm.VerticesColors[vertex]);
            };

            Assert.IsNotNull(algorithm.Distances);
            Assert.AreEqual(graph.VertexCount, algorithm.Distances.Count);

            Verify(algorithm, predecessors);
        }
コード例 #21
0
        private static void RunBFSAndCheck <TVertex, TEdge>(
            [NotNull] IUndirectedGraph <TVertex, TEdge> graph,
            [NotNull] TVertex sourceVertex)
            where TEdge : IEdge <TVertex>
        {
            var     parents         = new Dictionary <TVertex, TVertex>();
            var     distances       = new Dictionary <TVertex, int>();
            TVertex currentVertex   = default;
            int     currentDistance = 0;
            var     algorithm       = new UndirectedBreadthFirstSearchAlgorithm <TVertex, TEdge>(graph);

            algorithm.InitializeVertex += vertex =>
            {
                Assert.AreEqual(GraphColor.White, algorithm.VerticesColors[vertex]);
            };

            algorithm.StartVertex += vertex =>
            {
                Assert.AreEqual(GraphColor.White, algorithm.VerticesColors[vertex]);
            };

            algorithm.DiscoverVertex += vertex =>
            {
                Assert.AreEqual(GraphColor.Gray, algorithm.VerticesColors[vertex]);
                if (vertex.Equals(sourceVertex))
                {
                    currentVertex = sourceVertex;
                }
                else
                {
                    Assert.IsNotNull(currentVertex);
                    Assert.AreEqual(parents[vertex], currentVertex);
                    // ReSharper disable once AccessToModifiedClosure
                    Assert.AreEqual(distances[vertex], currentDistance + 1);
                    Assert.AreEqual(distances[vertex], distances[parents[vertex]] + 1);
                }
            };

            algorithm.ExamineEdge += edge =>
            {
                Assert.IsTrue(edge.Source.Equals(currentVertex) || edge.Target.Equals(currentVertex));
            };

            algorithm.ExamineVertex += vertex =>
            {
                TVertex u = vertex;
                currentVertex = u;
                // Ensure that the distances monotonically increase.
                // ReSharper disable AccessToModifiedClosure
                Assert.IsTrue(distances[u] == currentDistance || distances[u] == currentDistance + 1);

                if (distances[u] == currentDistance + 1) // New level
                {
                    ++currentDistance;
                }
                // ReSharper restore AccessToModifiedClosure
            };

            algorithm.TreeEdge += (sender, args) =>
            {
                TVertex u = args.Edge.Source;
                TVertex v = args.Edge.Target;
                if (algorithm.VerticesColors[v] == GraphColor.Gray)
                {
                    TVertex temp = u;
                    u = v;
                    v = temp;
                }

                Assert.AreEqual(GraphColor.White, algorithm.VerticesColors[v]);
                Assert.AreEqual(distances[u], currentDistance);
                parents[v]   = u;
                distances[v] = distances[u] + 1;
            };

            algorithm.NonTreeEdge += (sender, args) =>
            {
                TVertex u = args.Edge.Source;
                TVertex v = args.Edge.Target;
                if (algorithm.VerticesColors[v] != GraphColor.White)
                {
                    TVertex temp = u;
                    u = v;
                    v = temp;
                }

                Assert.IsFalse(algorithm.VerticesColors[v] == GraphColor.White);

                if (algorithm.VisitedGraph.IsDirected)
                {
                    // Cross or back edge
                    Assert.IsTrue(distances[v] <= distances[u] + 1);
                }
                else
                {
                    // Cross edge (or going backwards on a tree edge)
                    Assert.IsTrue(
                        distances[v] == distances[u] ||
                        distances[v] == distances[u] + 1 ||
                        distances[v] == distances[u] - 1);
                }
            };

            algorithm.GrayTarget += (sender, args) =>
            {
                Assert.AreEqual(GraphColor.Gray, algorithm.VerticesColors[args.Target]);
            };

            algorithm.BlackTarget += (sender, args) =>
            {
                Assert.AreEqual(GraphColor.Black, algorithm.VerticesColors[args.Target]);

                foreach (TEdge edge in algorithm.VisitedGraph.AdjacentEdges(args.Target))
                {
                    Assert.IsFalse(algorithm.VerticesColors[edge.Target] == GraphColor.White);
                }
            };

            algorithm.FinishVertex += vertex =>
            {
                Assert.AreEqual(GraphColor.Black, algorithm.VerticesColors[vertex]);
            };

            parents.Clear();
            distances.Clear();
            currentDistance = 0;

            foreach (TVertex vertex in graph.Vertices)
            {
                distances[vertex] = int.MaxValue;
                parents[vertex]   = vertex;
            }

            distances[sourceVertex] = 0;

            var recorder = new UndirectedVertexPredecessorRecorderObserver <TVertex, TEdge>();

            using (recorder.Attach(algorithm))
            {
                algorithm.Compute(sourceVertex);
            }

            // All white vertices should be unreachable from the source.
            foreach (TVertex vertex in graph.Vertices)
            {
                if (algorithm.VerticesColors[vertex] == GraphColor.White)
                {
                    // Check !IsReachable(sourceVertex, vertex, graph);
                    if (recorder.TryGetPath(vertex, out IEnumerable <TEdge> path))
                    {
                        foreach (TEdge edge in path)
                        {
                            Assert.AreNotEqual(sourceVertex, edge.Source);
                            Assert.AreNotEqual(sourceVertex, edge.Target);
                        }
                    }
                }
            }

            // The shortest path to a child should be one longer than
            // shortest path to the parent.
            foreach (TVertex vertex in graph.Vertices)
            {
                if (!parents[vertex].Equals(vertex)) // Not the root of the BFS tree
                {
                    Assert.AreEqual(distances[vertex], distances[parents[vertex]] + 1);
                }
            }
        }
コード例 #22
0
        public static void createTables()
        {
            // Create graph
            var graph = new UndirectedGraph<int, Edge<int>>();

            // Add vertices to the graph
            for (var i = 0; i < FormMain.nodes.Count; i++)
                graph.AddVertex(i);

            // Create edges
            var edgeCost = new Dictionary<Edge<int>, double>();
            for (var i = 0; i < FormMain.edges.Count; i++)
            {
                var quickGraphEdge = new Edge<int>(FormMain.nodes.IndexOf(FormMain.edges[i].nodes[0]), FormMain.nodes.IndexOf(FormMain.edges[i].nodes[1]));
                graph.AddEdge(quickGraphEdge);
                edgeCost.Add(quickGraphEdge, FormMain.edges[i].Weight);
            }

            // Initialize tables
            distanceTable = new double[FormMain.nodes.Count, FormMain.nodes.Count];
            pathTable = new List<int>[FormMain.nodes.Count, FormMain.nodes.Count];
            for (var i = 0; i < FormMain.nodes.Count; i++)
                for (var j = 0; j < FormMain.nodes.Count; j++)
                {
                    distanceTable[i, j] = double.PositiveInfinity;
                    pathTable[i, j] = new List<int>();
                }

            // Create tables
            for (var source = 0; source < FormMain.nodes.Count; source++)
            {
                // We want to use Dijkstra on this graph
                var dijkstra = new UndirectedDijkstraShortestPathAlgorithm<int, Edge<int>>(graph, edge => edgeCost[edge]);

                // attach a distance observer to give us the shortest path distances
                var distObserver = new UndirectedVertexDistanceRecorderObserver<int, Edge<int>>(edge => edgeCost[edge]);
                distObserver.Attach(dijkstra);

                // Attach a Vertex Predecessor Recorder Observer to give us the paths
                var predecessorObserver = new UndirectedVertexPredecessorRecorderObserver<int, Edge<int>>();
                predecessorObserver.Attach(dijkstra);

                // Run the algorithm for current Node
                dijkstra.Compute(source);

                // Add values to table
                foreach (var target in distObserver.Distances)
                {
                    distanceTable[source, target.Key] = target.Value;
                    IEnumerable<Edge<int>> path;
                    if (predecessorObserver.TryGetPath(target.Key, out path))
                        pathTable[source, target.Key].AddRange(path.Select(edge => edge.Source).Concat(path.Select(edge => edge.Target)).Distinct().OrderBy(next => distObserver.Distances[next]));
                }
            }

            // Create route tables
            foreach (var source in FormMain.nodes)
                source.routeTable = FormMain.nodes.ToDictionary(target => target, target =>
                    (
                        from edge in FormMain.edges
                        where edge.nodes.Contains(source)
                        let adjacent = edge.nodes[0] != source ? edge.nodes[0] : edge.nodes[1]
                        where !pathTable[adjacent.ID, target.ID].Contains(source.ID)
                        orderby edge.Weight + distanceTable[adjacent.ID, target.ID] ascending
                        select adjacent
                    ).ToList());

            TablesRequired = false;
        }
コード例 #23
0
        /// <summary>
        /// Compute
        /// </summary>
        private void Form_Load(object sender, EventArgs e)
        {
            // Crete distance table
            tableDijkstra.Columns.Add();
            tableDijkstra.Rows.Add(tableDijkstra.NewRow());
            for (var i = 0; i < FormMain.nodes.Count; i++)
            {
                tableDijkstra.Columns.Add();
                tableDijkstra.Rows.Add(tableDijkstra.NewRow());
                tableDijkstra.Rows[0][i + 1] = tableDijkstra.Rows[i + 1][0] = i;
            }

            // Create graph
            var graph = new UndirectedGraph <int, Edge <int> >();

            // Add vertices to the graph
            for (var i = 0; i < FormMain.nodes.Count; i++)
            {
                graph.AddVertex(i);
            }

            // Create edges
            for (var i = 0; i < FormMain.edges.Count; i++)
            {
                var quickGraphEdge = new Edge <int>(FormMain.nodes.IndexOf(FormMain.edges[i].nodes[0]), FormMain.nodes.IndexOf(FormMain.edges[i].nodes[1]));
                graph.AddEdge(quickGraphEdge);
            }

            // Compute distances
            for (var source = 0; source < FormMain.nodes.Count; source++)
            {
                // We want to use Dijkstra on this graph
                var dijkstra = new UndirectedDijkstraShortestPathAlgorithm <int, Edge <int> >(graph, edge => 1);

                // attach a distance observer to give us the shortest path distances
                var distObserver = new UndirectedVertexDistanceRecorderObserver <int, Edge <int> >(edge => 1);
                distObserver.Attach(dijkstra);

                // Attach a Vertex Predecessor Recorder Observer to give us the paths
                var predecessorObserver = new UndirectedVertexPredecessorRecorderObserver <int, Edge <int> >();
                predecessorObserver.Attach(dijkstra);

                // Run the algorithm for current Node
                dijkstra.Compute(source);

                // Show distances
                foreach (var target in distObserver.Distances)
                {
                    tableDijkstra.Rows[source + 1][target.Key + 1] = target.Value.ToString();
                    IEnumerable <Edge <int> > edgePath;
                    if (predecessorObserver.TryGetPath(target.Key, out edgePath))
                    {
                        string str = " (";
                        foreach (var nodeID in edgePath.Select(edge => edge.Source).Concat(edgePath.Select(edge => edge.Target)).Distinct().OrderBy(next => distObserver.Distances[next]))
                        {
                            str += string.Format("{0}->", nodeID);
                        }
                        tableDijkstra.Rows[source + 1][target.Key + 1] += str.Substring(0, str.Length - 2) + ")";
                    }
                }
            }
            dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader;
        }
コード例 #24
0
        public static string ShortestWayDijsktraAlgorithmUnDirected(GraphVertex vertexD, List <GraphEdge> listEdge, List <GraphVertex> listVertex)
        {
            string s = "";
            UndirectedGraph <GraphVertex, UndirectedEdge <GraphVertex> > graph = new UndirectedGraph <GraphVertex, UndirectedEdge <GraphVertex> >();

            foreach (var vert in listVertex)
            {
                graph.AddVertex(vert);
            }
            foreach (var edge in listEdge)
            {
                graph.AddEdge(new UndirectedEdge <GraphVertex>(edge.StartVertex, edge.EndVertex));
            }
            Dictionary <UndirectedEdge <GraphVertex>, double> edgeCost = new Dictionary <UndirectedEdge <GraphVertex>, double>();

            int i = 0;

            foreach (var edge in graph.Edges)
            {
                double eCost = EdgeCostSearching(edge.Source, edge.Target, listEdge);
                edgeCost.Add(edge, eCost);
                i++;
            }

            IEnumerable <UndirectedEdge <GraphVertex> > pathh;
            Func <UndirectedEdge <GraphVertex>, double> getW = edge => edgeCost[edge];
            UndirectedDijkstraShortestPathAlgorithm <GraphVertex, UndirectedEdge <GraphVertex> >  diijkstra = new UndirectedDijkstraShortestPathAlgorithm <GraphVertex, UndirectedEdge <GraphVertex> >(graph, getW);
            UndirectedVertexDistanceRecorderObserver <GraphVertex, UndirectedEdge <GraphVertex> > distObs   = new UndirectedVertexDistanceRecorderObserver <GraphVertex, UndirectedEdge <GraphVertex> >(getW);

            using (distObs.Attach(diijkstra))
            {
                UndirectedVertexPredecessorRecorderObserver <GraphVertex, UndirectedEdge <GraphVertex> > predObs = new UndirectedVertexPredecessorRecorderObserver <GraphVertex, UndirectedEdge <GraphVertex> >();
                using (predObs.Attach(diijkstra))
                {
                    diijkstra.Compute(vertexD);

                    foreach (KeyValuePair <GraphVertex, double> kvp in distObs.Distances)
                    {
                        s += "From " + vertexD.Name + " to " + kvp.Key.Name + " is " + kvp.Value + "         by ";
                        if (predObs.TryGetPath(kvp.Key, out pathh))
                        {
                            foreach (var t in pathh)
                            {
                                s += "edge " + t.Source.Name + "<->" + t.Target.Name + " ";
                            }
                        }
                        s += System.Environment.NewLine;
                    }
                }
            }
            return(s);
        }
コード例 #25
0
        public static void createTables()
        {
            // Create graph
            var graph = new UndirectedGraph <int, Edge <int> >();

            // Add vertices to the graph
            for (var i = 0; i < FormMain.nodes.Count; i++)
            {
                graph.AddVertex(i);
            }

            // Create edges
            var edgeCost = new Dictionary <Edge <int>, double>();

            for (var i = 0; i < FormMain.edges.Count; i++)
            {
                var quickGraphEdge = new Edge <int>(FormMain.nodes.IndexOf(FormMain.edges[i].nodes[0]), FormMain.nodes.IndexOf(FormMain.edges[i].nodes[1]));
                graph.AddEdge(quickGraphEdge);
                edgeCost.Add(quickGraphEdge, FormMain.edges[i].Weight);
            }

            // Initialize tables
            distanceTable = new double[FormMain.nodes.Count, FormMain.nodes.Count];
            pathTable     = new List <int> [FormMain.nodes.Count, FormMain.nodes.Count];
            for (var i = 0; i < FormMain.nodes.Count; i++)
            {
                for (var j = 0; j < FormMain.nodes.Count; j++)
                {
                    distanceTable[i, j] = double.PositiveInfinity;
                    pathTable[i, j]     = new List <int>();
                }
            }

            // Create tables
            for (var source = 0; source < FormMain.nodes.Count; source++)
            {
                // We want to use Dijkstra on this graph
                var dijkstra = new UndirectedDijkstraShortestPathAlgorithm <int, Edge <int> >(graph, edge => edgeCost[edge]);

                // attach a distance observer to give us the shortest path distances
                var distObserver = new UndirectedVertexDistanceRecorderObserver <int, Edge <int> >(edge => edgeCost[edge]);
                distObserver.Attach(dijkstra);

                // Attach a Vertex Predecessor Recorder Observer to give us the paths
                var predecessorObserver = new UndirectedVertexPredecessorRecorderObserver <int, Edge <int> >();
                predecessorObserver.Attach(dijkstra);

                // Run the algorithm for current Node
                dijkstra.Compute(source);

                // Add values to table
                foreach (var target in distObserver.Distances)
                {
                    distanceTable[source, target.Key] = target.Value;
                    IEnumerable <Edge <int> > path;
                    if (predecessorObserver.TryGetPath(target.Key, out path))
                    {
                        pathTable[source, target.Key].AddRange(path.Select(edge => edge.Source).Concat(path.Select(edge => edge.Target)).Distinct().OrderBy(next => distObserver.Distances[next]));
                    }
                }
            }

            // Create route tables
            foreach (var source in FormMain.nodes)
            {
                source.routeTable = FormMain.nodes.ToDictionary(target => target, target =>
                                                                (
                                                                    from edge in FormMain.edges
                                                                    where edge.nodes.Contains(source)
                                                                    let adjacent = edge.nodes[0] != source ? edge.nodes[0] : edge.nodes[1]
                                                                                   where !pathTable[adjacent.ID, target.ID].Contains(source.ID)
                                                                                   orderby edge.Weight + distanceTable[adjacent.ID, target.ID] ascending
                                                                                   select adjacent
                                                                ).ToList());
            }

            TablesRequired = false;
        }
        public void Attach()
        {
            // Undirected DFS is used for tests but result may change if using another search algorithm
            // or another starting point
            {
                var recorder = new UndirectedVertexPredecessorRecorderObserver <int, Edge <int> >();

                var graph = new UndirectedGraph <int, Edge <int> >();

                var dfs = new UndirectedDepthFirstSearchAlgorithm <int, Edge <int> >(graph);
                using (recorder.Attach(dfs))
                {
                    dfs.Compute();

                    CollectionAssert.IsEmpty(recorder.VerticesPredecessors);
                }
            }

            {
                var recorder = new UndirectedVertexPredecessorRecorderObserver <int, Edge <int> >();

                var graph = new UndirectedGraph <int, Edge <int> >();
                graph.AddVertexRange(new[] { 1, 2 });

                var dfs = new UndirectedDepthFirstSearchAlgorithm <int, Edge <int> >(graph);
                using (recorder.Attach(dfs))
                {
                    dfs.Compute();

                    CollectionAssert.IsEmpty(recorder.VerticesPredecessors);
                }
            }

            {
                var recorder = new UndirectedVertexPredecessorRecorderObserver <int, Edge <int> >();

                var edge12 = new Edge <int>(1, 2);
                var edge14 = new Edge <int>(1, 4);
                var edge31 = new Edge <int>(3, 1);
                var edge33 = new Edge <int>(3, 3);
                var edge34 = new Edge <int>(3, 4);
                var edge42 = new Edge <int>(4, 2);
                var graph  = new UndirectedGraph <int, Edge <int> >();
                graph.AddVerticesAndEdgeRange(new[]
                {
                    edge12, edge14, edge31, edge33, edge34, edge42
                });

                var dfs = new UndirectedDepthFirstSearchAlgorithm <int, Edge <int> >(graph);
                using (recorder.Attach(dfs))
                {
                    dfs.Compute();

                    CollectionAssert.AreEqual(
                        new Dictionary <int, Edge <int> >
                    {
                        [2] = edge12,
                        [3] = edge34,
                        [4] = edge42
                    },
                        recorder.VerticesPredecessors);
                }
            }
        }