コード例 #1
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));
        }
コード例 #2
0
        public static UndirectedBreadthFirstSearchAlgorithm <T, Edge <T> > CreateAlgorithmAndMaybeDoComputation <T>(
            [NotNull] ContractScenario <T> scenario)
        {
            var graph = new UndirectedGraph <T, Edge <T> >();

            graph.AddVerticesAndEdgeRange(scenario.EdgesInGraph.Select(e => new Edge <T>(e.Source, e.Target)));
            graph.AddVertexRange(scenario.SingleVerticesInGraph);

            var algorithm = new UndirectedBreadthFirstSearchAlgorithm <T, Edge <T> >(graph);

            if (scenario.DoComputation)
            {
                algorithm.Compute(scenario.Root);
            }
            return(algorithm);
        }
コード例 #3
0
        public void GetVertexColor()
        {
            var graph = new UndirectedGraph <int, Edge <int> >();

            graph.AddVerticesAndEdge(new Edge <int>(1, 2));

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

            // Algorithm not run
            // ReSharper disable once ReturnValueOfPureMethodIsNotUsed
            Assert.Throws <VertexNotFoundException>(() => algorithm.GetVertexColor(1));

            algorithm.Compute(1);

            Assert.AreEqual(GraphColor.Black, algorithm.GetVertexColor(1));
            Assert.AreEqual(GraphColor.Black, algorithm.GetVertexColor(2));
        }
コード例 #4
0
ファイル: Core.cs プロジェクト: DrzwiPercepcji/MGR_tests
        private void BFS()
        {
            watch.Restart();

            var found = new List <int>();
            var bfs   = new UndirectedBreadthFirstSearchAlgorithm <int, Edge>(graph);

            bfs.DiscoverVertex += v => found.Add(v);
            bfs.Compute(0);

            watch.Stop();

            span        = watch.Elapsed;
            elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", span.Hours, span.Minutes, span.Seconds, span.Milliseconds / 10);

            Console.WriteLine("BFS time: " + elapsedTime);
            Console.WriteLine("BFS elements: " + found.Count);

            foreach (int index in indexes)
            {
                Console.WriteLine(index + ": " + found[index]);
            }
        }
コード例 #5
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);
                }
            }
        }
コード例 #6
0
        private void Search(IUndirectedGraph<string,Edge<string>> graph, string rootVertex)
        {
            Console.WriteLine(rootVertex);
            algo = new UndirectedBreadthFirstSearchAlgorithm<string,Edge<string>>(graph);
            try
            {
                algo.InitializeVertex += new VertexEventHandler<string>(this.InitializeVertex);
                algo.DiscoverVertex += new VertexEventHandler<string>(this.DiscoverVertex);
                algo.ExamineVertex += new VertexEventHandler<string>(this.ExamineVertex);
                algo.TreeEdge += new EdgeEventHandler<string,Edge<string>>(this.TreeEdge);
                algo.NonTreeEdge += new EdgeEventHandler<string,Edge<string>>(this.NonTreeEdge);
                algo.GrayTarget += new EdgeEventHandler<string,Edge<string>>(this.GrayTarget);
                algo.BlackTarget += new EdgeEventHandler<string,Edge<string>>(this.BlackTarget);
                algo.FinishVertex += new VertexEventHandler<string>(this.FinishVertex);

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

                foreach (string v in this.algo.VisitedGraph.Vertices)
                {
                    distances[v] = int.MaxValue;
                    parents[v] = v;
                }
                distances[sourceVertex] = 0;
                algo.Compute(sourceVertex);

                CheckBfs();
            }
            finally
            {
                algo.InitializeVertex -= new VertexEventHandler<string>(this.InitializeVertex);
                algo.DiscoverVertex -= new VertexEventHandler<string>(this.DiscoverVertex);
                algo.ExamineVertex -= new VertexEventHandler<string>(this.ExamineVertex);
                algo.TreeEdge -= new EdgeEventHandler<string,Edge<string>>(this.TreeEdge);
                algo.NonTreeEdge -= new EdgeEventHandler<string,Edge<string>>(this.NonTreeEdge);
                algo.GrayTarget -= new EdgeEventHandler<string,Edge<string>>(this.GrayTarget);
                algo.BlackTarget -= new EdgeEventHandler<string,Edge<string>>(this.BlackTarget);
                algo.FinishVertex -= new VertexEventHandler<string>(this.FinishVertex);
            }
        }