예제 #1
0
        public void TestDigraph()
        {
            Random rand = new Random();
            int v = rand.Next(10, 30);

            Digraph g = new Digraph(v);
            int e0 = rand.Next(10, 30);
            string strs = string.Empty;
            for (int i = 0; i < e0; i++)
            {
                int v1 = rand.Next(0, v);
                int v2 = rand.Next(0, v);
                string str = v1 + " - " + v2 + ",";
                string str1 = v2 + " - " + v1 + ",";

                if (v1 == v2 || strs.Contains(str) || strs.Contains(str1))
                {
                    i--;
                    continue;
                }

                g.AddEdge(v1, v2);
                strs += str;
            }

            Debug.WriteLine("input e: " + strs);
            Debug.WriteLine(g.ToString());

            Digraph g1 = new Digraph(g);
            Debug.WriteLine("g1: ");
            Debug.WriteLine(g1.ToString());
        }
예제 #2
0
        /// <summary>
        /// check that algorithm computes either the topological order or finds a directed this.Cycle
        /// </summary>
        /// <param name="g"></param>
        /// <param name="v"></param>
        private void dfs(Digraph g, int v)
        {
            this._onStack[v] = true;
            this._marked[v] = true;

            foreach (int w in g.Adj[v])
                if (this.Cycle != null)
                {
                    // short circuit if directed this.Cycle found
                    return;
                }
                else if (!this._marked[w])
                {
                    //found new vertex, so recur
                    this._edgeTo[w] = v;
                    this.dfs(g, w);
                }
                else if (this._onStack[w])
                {
                    // trace back directed this.Cycle
                    this.Cycle = new Stack<int>();
                    for (int x = v; x != w; x = this._edgeTo[x])
                        this.Cycle.Push(x);

                    this.Cycle.Push(w);
                    this.Cycle.Push(v);
                }

            this._onStack[v] = false;
        }
예제 #3
0
 /// <summary>
 /// Computes the vertices in digraph G that are to any of the source vertices sources.
 /// </summary>
 /// <param name="g"></param>
 /// <param name="sources"></param>
 public DirectedDFS(Digraph g, IEnumerable<int> sources)
 {
     this.Marked = new bool[g.V];
     foreach (int v in sources)
         if (!this.Marked[v])
             this.dfs(g, v);
 }
예제 #4
0
파일: Digraph.cs 프로젝트: qizl/Algorithms
 public Digraph Reverse()
 {
     Digraph r = new Digraph(V);
     for (int v = 0; v < V; v++)
         foreach (int w in this.Adj[v])
             r.AddEdge(w, v);
     return r;
 }
예제 #5
0
 private void dfs(Digraph g, int v)
 {
     this.Marked[v] = true;
     this.ID[v] = this.Count;
     foreach (int w in g.Adj[v])
         if (!this.Marked[w])
             this.dfs(g, w);
 }
예제 #6
0
 public Topological(Digraph g)
 {
     DirectedCycle cycleFinder = new DirectedCycle(g);
     if (!cycleFinder.HasCycle())
     {
         DepthFirstOrder dfs = new DepthFirstOrder(g);
         this.Order = dfs.ReversePost;
     }
 }
예제 #7
0
        /// <summary>
        /// Determines whether the digraph G has a directed this.Cycle and, if so, finds such a this.Cycle
        /// </summary>
        /// <param name="g"></param>
        public DirectedCycle(Digraph g)
        {
            this._marked = new bool[g.V];
            this._onStack = new bool[g.V];
            this._edgeTo = new int[g.V];

            for (int v = 0; v < g.V; v++)
                if (!this._marked[v] && this.Cycle == null)
                    this.dfs(g, v);
        }
예제 #8
0
        public DepthFirstOrder(Digraph g)
        {
            this.Pre = new Queue<int>();
            this.Post = new Queue<int>();
            this.ReversePost = new Stack<int>();
            this._marked = new bool[g.V];

            for (int v = 0; v < g.V; v++)
                if (!this._marked[v])
                    this.dfs(g, v);
        }
예제 #9
0
        private void dfs(Digraph g, int v)
        {
            this.Pre.Enqueue(v);

            this._marked[v] = true;
            foreach (int w in g.Adj[v])
                if (!this._marked[w])
                    this.dfs(g, w);

            this.Post.Enqueue(v);
            this.ReversePost.Push(v);
        }
예제 #10
0
파일: Digraph.cs 프로젝트: qizl/Algorithms
 public Digraph(Digraph g)
     : this(g.V)
 {
     this.E = g.E;
     for (int v = 0; v < g.V; v++)
     {
         Part1.Stack<int> reverse = new Part1.Stack<int>();
         foreach (int w in g.Adj[v])
             reverse.Push(w);
         foreach (int w in reverse)
             this.Adj[v].Add(w);
     }
 }
예제 #11
0
        /// <summary>
        /// Computes the connected components of the directed graph G.
        /// </summary>
        /// <param name="g"></param>
        public KosarajuSCC(Digraph g)
        {
            this.Marked = new bool[g.V];
            this.ID = new int[g.V];

            DepthFirstOrder order = new DepthFirstOrder(g.Reverse());
            foreach (int v in order.ReversePost)
                if (!this.Marked[v])
                {
                    this.dfs(g, v);
                    this.Count++;
                }
        }
예제 #12
0
        public void TestDirectedCycle()
        {
            Digraph g = new Digraph(6);
            g.AddEdge(0, 5);
            g.AddEdge(5, 4);
            g.AddEdge(4, 3);
            g.AddEdge(3, 5);
            g.AddEdge(0, 1);
            g.AddEdge(1, 2);
            g.AddEdge(2, 3);
            Debug.WriteLine(g.ToString());

            DirectedCycle finder = new DirectedCycle(g);
            if (finder.HasCycle())
            {
                Debug.WriteLine("Directed cycle:");
                foreach (var v in finder.Cycle)
                    Debug.Write(" => " + v);
            }
            else
                Debug.WriteLine("No directed cycle!");
        }
예제 #13
0
        public void TestKosarajuSCCHasNotCycle()
        {
            Digraph g = new Digraph(6);
            g.AddEdge(0, 1);
            g.AddEdge(1, 2);
            g.AddEdge(2, 3);
            g.AddEdge(0, 4);
            g.AddEdge(4, 5);
            Debug.WriteLine(g.ToString());

            DepthFirstOrder dfs = new DepthFirstOrder(g);
            StringBuilder sb = new StringBuilder();
            foreach (var item in dfs.ReversePost)
                sb.Append(item + " ");
            Debug.WriteLine(sb.ToString());

            KosarajuSCC scc = new KosarajuSCC(g);
            sb.Clear();
            for (int i = 0; i < scc.ID.Length; i++)
                sb.Append(i + " - " + scc.ID[i] + Environment.NewLine);
            Debug.WriteLine(sb.ToString());
        }
예제 #14
0
 /// <summary>
 /// Computes the vertices in digraph G that are reachable from the source vertex s.
 /// </summary>
 /// <param name="g"></param>
 /// <param name="s"></param>
 public DirectedDFS(Digraph g, int s)
 {
     this.Marked = new bool[g.V];
     this.dfs(g, s);
 }
예제 #15
0
 public TransitiveClosure(Digraph g)
 {
     this._all = new DirectedDFS[g.V];
     for (int v = 0; v < g.V; v++)
         this._all[v] = new DirectedDFS(g, v);
 }