Exemplo n.º 1
0
        /// <summary>
        /// Create an arbitrary matching on the subset of vertices ('s') of provided
        /// graph. The provided matching should be empty.
        ///
        /// <param name="g">graph to match</param>
        /// <param name="m">empty matching (presumed)</param>
        /// <param name="s">subset of vertices</param>
        /// <returns>number of vertices matched</returns>
        /// </summary>
        public static int Initial(Graph g, Matching m, BitArray s)
        {
            int nMatched = 0;

            for (int v = BitArrays.NextSetBit(s, 0); v >= 0; v = BitArrays.NextSetBit(s, v + 1))
            {
                // skip if already matched
                if (m.Matched(v))
                {
                    continue;
                }

                // find a single edge which is not matched and match it
                int d = g.Degree(v);
                for (int j = 0; j < d; ++j)
                {
                    Edge e = g.EdgeAt(v, j);
                    int  w = e.Other(v);
                    if ((e.Bond != Bond.Single) && m.Unmatched(w) && s[w])
                    {
                        m.Match(v, w);
                        nMatched += 2;
                        break;
                    }
                }
            }

            return(nMatched);
        }
Exemplo n.º 2
0
        /// <summary>
        /// When precisely two vertices are unmatched we only need to find a single
        /// augmenting path. Rather than run through edmonds with blossoms etc we
        /// simple do a targest DFS for the path.
        ///
        /// <param name="g">graph</param>
        /// <param name="m">matching</param>
        /// <param name="nMatched">current matching cardinality must be |s|-nMathced == 2</param>
        /// <param name="s">subset size</param>
        /// <returns>new match cardinality</returns>
        /// </summary>
        public static int AugmentOnce(Graph g, Matching m, int nMatched, BitArray s)
        {
            int vStart = BitArrays.NextSetBit(s, 0);

            while (vStart >= 0)
            {
                if (!m.Matched(vStart))
                {
                    break;
                }
                vStart = BitArrays.NextSetBit(s, vStart + 1);
            }
            int vEnd = BitArrays.NextSetBit(s, vStart + 1);

            while (vEnd >= 0)
            {
                if (!m.Matched(vEnd))
                {
                    break;
                }
                vEnd = BitArrays.NextSetBit(s, vEnd + 1);
            }

            // find an augmenting path between vStart and vEnd
            int[] path = new int[g.Order];
            int   len  = FindPath(g, vStart, vEnd, s, path, 0, m, false);

            if (len > 0)
            {
                // augment
                for (int i = 0; i < len; i += 2)
                {
                    m.Match(path[i], path[i + 1]);
                }
                nMatched += 2;
            }

            return(nMatched);
        }
Exemplo n.º 3
0
        public static int Dfs(Graph g, Matching m, BitArray s)
        {
            int      nMatched  = 0;
            BitArray unvisited = (BitArray)s.Clone();

            // visit those with degree 1 first and expand out matching
            for (int v = BitArrays.NextSetBit(unvisited, 0); v >= 0; v = BitArrays.NextSetBit(unvisited, v + 1))
            {
                if (!m.Matched(v))
                {
                    int cnt = 0;
                    int d   = g.Degree(v);
                    while (--d >= 0)
                    {
                        int w = g.EdgeAt(v, d).Other(v);
                        if (unvisited[w])
                        {
                            ++cnt;
                        }
                    }
                    if (cnt == 1)
                    {
                        nMatched += DfsVisit(g, v, m, unvisited, true);
                    }
                }
            }

            // now those which aren't degree 1
            for (int v = BitArrays.NextSetBit(unvisited, 0); v >= 0; v = BitArrays.NextSetBit(unvisited, v + 1))
            {
                if (!m.Matched(v))
                {
                    nMatched += DfsVisit(g, v, m, unvisited, true);
                }
            }

            return(nMatched);
        }