示例#1
0
        /// <summary>
        /// Find an augmenting path an alternate it's matching. If an augmenting path
        /// was found then the search must be restarted. If a blossom was detected
        /// the blossom is contracted and the search continues.
        /// </summary>
        /// <returns>an augmenting path was found</returns>
        private bool Augment()
        {
            // reset data structures
            Arrays.Fill(even, nil);
            Arrays.Fill(odd, nil);
            uf.Clear();
            bridges.Clear();
            queue.Clear();

            // queue every unmatched vertex and place in the
            // even level (level = 0)
            for (int v = 0; v < graph.Order; v++)
            {
                if (subset.Contains(v) && matching.Unmatched(v))
                {
                    even[v] = v;
                    queue.Enqueue(v);
                }
            }

            // for each 'free' vertex, start a bfs search
            while (!queue.IsEmpty())
            {
                int v = queue.Poll();

                int d = graph.Degree(v);
                for (int j = 0; j < d; ++j)
                {
                    Edge e = graph.EdgeAt(v, j);
                    if (e.Bond == Bond.Single)
                    {
                        continue;
                    }
                    int w = e.Other(v);

                    if (!subset.Contains(w))
                    {
                        continue;
                    }

                    // the endpoints of the edge are both at even levels in the
                    // forest - this means it is either an augmenting path or
                    // a blossom
                    if (even[uf.Find(w)] != nil)
                    {
                        if (Check(v, w))
                        {
                            return(true);
                        }
                    }

                    // add the edge to the forest if is not already and extend
                    // the tree with this matched edge
                    else if (odd[w] == nil)
                    {
                        odd[w] = v;
                        int u = matching.Other(w);
                        // add the matched edge (potential though a blossom) if it
                        // isn't in the forest already
                        if (even[uf.Find(u)] == nil)
                        {
                            even[u] = w;
                            queue.Enqueue(u);
                        }
                    }
                }
            }

            // no augmenting paths, matching is maximum
            return(false);
        }