예제 #1
0
 public void Init()
 {
     this.parents         = new Dictionary <string, string>();
     this.distances       = new Dictionary <string, int>();
     this.currentDistance = 0;
     this.currentVertex   = null;
     this.algo            = null;
 }
예제 #2
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);
            }
        }
        public void RunBfs <TVertex, TEdge>(IUndirectedGraph <TVertex, TEdge> g, TVertex sourceVertex)
            where TEdge : IEdge <TVertex>
        {
            var     parents         = new Dictionary <TVertex, TVertex>();
            var     distances       = new Dictionary <TVertex, int>();
            TVertex currentVertex   = default(TVertex);
            int     currentDistance = 0;
            var     algo            = new UndirectedBreadthFirstSearchAlgorithm <TVertex, TEdge>(g);

            algo.InitializeVertex += u =>
            {
                Assert.AreEqual(algo.VertexColors[u], GraphColor.White);
            };

            algo.DiscoverVertex += u =>
            {
                Assert.AreEqual(algo.VertexColors[u], GraphColor.Gray);
                if (u.Equals(sourceVertex))
                {
                    currentVertex = sourceVertex;
                }
                else
                {
                    Assert.IsNotNull(currentVertex);
                    Assert.AreEqual(parents[u], currentVertex);
                    Assert.AreEqual(distances[u], currentDistance + 1);
                    Assert.AreEqual(distances[u], distances[parents[u]] + 1);
                }
            };
            algo.ExamineEdge += args =>
            {
                Assert.IsTrue(args.Source.Equals(currentVertex) ||
                              args.Target.Equals(currentVertex));
            };

            algo.ExamineVertex += args =>
            {
                var u = args;
                currentVertex = u;
                // Ensure that the distances monotonically increase.
                Assert.IsTrue(
                    distances[u] == currentDistance ||
                    distances[u] == currentDistance + 1
                    );

                if (distances[u] == currentDistance + 1) // new level
                {
                    ++currentDistance;
                }
            };
            algo.TreeEdge += (sender, args) =>
            {
                var u = args.Edge.Source;
                var v = args.Edge.Target;
                if (algo.VertexColors[v] == GraphColor.Gray)
                {
                    var temp = u;
                    u = v;
                    v = temp;
                }

                Assert.AreEqual(algo.VertexColors[v], GraphColor.White);
                Assert.AreEqual(distances[u], currentDistance);
                parents[v]   = u;
                distances[v] = distances[u] + 1;
            };
            algo.NonTreeEdge += (sender, args) =>
            {
                var u = args.Edge.Source;
                var v = args.Edge.Target;
                if (algo.VertexColors[v] != GraphColor.White)
                {
                    var temp = u;
                    u = v;
                    v = temp;
                }

                Assert.IsFalse(algo.VertexColors[v] == GraphColor.White);

                if (algo.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
                        );
                }
            };

            algo.GrayTarget += (sender, args) =>
            {
                //Assert.AreEqual(algo.VertexColors[args.Edge.Target], GraphColor.Gray);
            };
            algo.BlackTarget += (sender, args) =>
            {
                //Assert.AreEqual(algo.VertexColors[args.Edge.Target], GraphColor.Black);

                //foreach (var e in algo.VisitedGraph.AdjacentEdges(args.Edge.Target))
                //    Assert.IsFalse(algo.VertexColors[e.Target] == GraphColor.White);
            };

            algo.FinishVertex += args =>
            {
                Assert.AreEqual(algo.VertexColors[args], GraphColor.Black);
            };


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

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

            // All white vertices should be unreachable from the source.
            foreach (var v in g.Vertices)
            {
                if (algo.VertexColors[v] == GraphColor.White)
                {
                    //!IsReachable(start,u,g);
                }
            }

            // The shortest path to a child should be one longer than
            // shortest path to the parent.
            foreach (var v in g.Vertices)
            {
                if (!parents[v].Equals(v)) // *ui not the root of the bfs tree
                {
                    Assert.AreEqual(distances[v], distances[parents[v]] + 1);
                }
            }
        }