コード例 #1
0
ファイル: BipartiteX.cs プロジェクト: zzhi/Algs4Net
        public static void MainTest(string[] args)
        {
            int V1 = int.Parse(args[0]);
            int V2 = int.Parse(args[1]);
            int E  = int.Parse(args[2]);
            int F  = int.Parse(args[3]);

            BipartiteX b;
            // create random bipartite graph with V1 vertices on left side,
            // V2 vertices on right side, and E edges; then add F random edges
            Graph G = GraphGenerator.Bipartite(V1, V2, E);

            Console.WriteLine("Graph is {0}\n", G);

            b = new BipartiteX(G);
            BipartiteXReport(b);

            for (int i = 0; i < F; i++)
            {
                int v = StdRandom.Uniform(V1 + V2);
                int w = StdRandom.Uniform(V1 + V2);
                G.AddEdge(v, w);
            }
            Console.WriteLine("After adding {0} random edges", F);
            Console.WriteLine("Graph is {0}\n", G);

            b = new BipartiteX(G);
            BipartiteXReport(b);
        }
コード例 #2
0
        private int[] edgeTo;             // edgeTo[v] = w if v-w is last edge on path to w

        /// <summary>
        /// Determines a maximum matching (and a minimum vertex cover)
        /// in a bipartite graph.</summary>
        /// <param name="G">the bipartite graph</param>
        /// <exception cref="ArgumentException">if <c>G</c> is not bipartite</exception>
        ///
        public BipartiteMatching(Graph G)
        {
            bipartition = new BipartiteX(G);
            if (!bipartition.IsBipartite)
            {
                throw new ArgumentException("graph is not bipartite");
            }

            numVertices = G.V;

            // initialize empty matching
            mate = new int[numVertices];
            for (int v = 0; v < numVertices; v++)
            {
                mate[v] = UNMATCHED;
            }

            // alternating path algorithm
            while (hasAugmentingPath(G))
            {
                // find one endpoint t in alternating path
                int t = -1;
                for (int v = 0; v < numVertices; v++)
                {
                    if (!IsMatched(v) && edgeTo[v] != -1)
                    {
                        t = v;
                        break;
                    }
                }

                // update the matching according to alternating path in edgeTo[] array
                for (int v = t; v != -1; v = edgeTo[edgeTo[v]])
                {
                    int w = edgeTo[v];
                    mate[v] = w;
                    mate[w] = v;
                }
                cardinality++;
            }

            // find min vertex cover from marked[] array
            inMinVertexCover = new bool[numVertices];
            for (int v = 0; v < numVertices; v++)
            {
                if (bipartition.Color(v) && !marked[v])
                {
                    inMinVertexCover[v] = true;
                }
                if (!bipartition.Color(v) && marked[v])
                {
                    inMinVertexCover[v] = true;
                }
            }
            Debug.Assert(certifySolution(G));
        }
コード例 #3
0
ファイル: BipartiteX.cs プロジェクト: zzhi/Algs4Net
 private static void BipartiteXReport(BipartiteX b)
 {
     if (b.IsBipartite)
     {
         Graph G = b.G;
         Console.WriteLine("Graph is bipartite");
         for (int v = 0; v < G.V; v++)
         {
             Console.WriteLine(v + ": " + b.Color(v));
         }
     }
     else
     {
         Console.Write("Graph has an odd-length cycle: ");
         foreach (int x in b.OddCycle())
         {
             Console.Write(x + " ");
         }
     }
     Console.WriteLine();
 }
コード例 #4
0
        private int[] distTo;            // distTo[v] = number of edges on shortest path to v

        /// <summary>
        /// Determines a maximum matching (and a minimum vertex cover)
        /// in a bipartite graph.</summary>
        /// <param name="G">the bipartite graph</param>
        /// <exception cref="ArgumentException">if <c>G</c> is not bipartite</exception>
        ///
        public HopcroftKarp(Graph G)
        {
            bipartition = new BipartiteX(G);
            if (!bipartition.IsBipartite)
            {
                throw new ArgumentException("graph is not bipartite");
            }

            // initialize empty matching
            this.V = G.V;
            mate   = new int[V];
            for (int v = 0; v < V; v++)
            {
                mate[v] = UNMATCHED;
            }

            // the call to hasAugmentingPath() provides enough info to reconstruct level graph
            while (hasAugmentingPath(G))
            {
                // to be able to iterate over each adjacency list, keeping track of which
                // vertex in each adjacency list needs to be explored next
                IEnumerator <int>[] adj = new IEnumerator <int> [G.V];
                for (int v = 0; v < G.V; v++)
                {
                    adj[v] = G.Adj(v).GetEnumerator();
                }

                // for each unmatched vertex s on one side of bipartition
                for (int s = 0; s < V; s++)
                {
                    if (IsMatched(s) || !bipartition.Color(s))
                    {
                        continue;                                // or use distTo[s] == 0
                    }
                    // find augmenting path from s using nonrecursive DFS
                    LinkedStack <int> path = new LinkedStack <int>();
                    path.Push(s);
                    while (!path.IsEmpty)
                    {
                        int v = path.Peek();

                        // retreat, no more edges in level graph leaving v
                        if (!adj[v].MoveNext())
                        {
                            path.Pop();
                        }

                        // advance
                        else
                        {
                            // process edge v-w only if it is an edge in level graph
                            int w = adj[v].Current;
                            if (!isLevelGraphEdge(v, w))
                            {
                                continue;
                            }

                            // add w to augmenting path
                            path.Push(w);

                            // augmenting path found: update the matching
                            if (!IsMatched(w))
                            {
                                // Console.WriteLine("augmenting path: " + toString(path));

                                while (!path.IsEmpty)
                                {
                                    int x = path.Pop();
                                    int y = path.Pop();
                                    mate[x] = y;
                                    mate[y] = x;
                                }
                                cardinality++;
                            }
                        }
                    }
                }
            }

            // also find a min vertex cover
            inMinVertexCover = new bool[V];
            for (int v = 0; v < V; v++)
            {
                if (bipartition.Color(v) && !marked[v])
                {
                    inMinVertexCover[v] = true;
                }
                if (!bipartition.Color(v) && marked[v])
                {
                    inMinVertexCover[v] = true;
                }
            }

            Debug.Assert(certifySolution(G));
        }