Example #1
0
        [TestMethod()] public void Adjusted_contains()
        {
            Matching matching = Matching.CreateEmpty(Graph.FromSmiles("CCCCC"));

            matching.Match(0, 1);
            matching.Match(2, 3);
            matching.Match(1, 2); // 0-1 and 2-3 should not be

            Assert.IsFalse(matching.Unmatched(1));
            Assert.IsFalse(matching.Unmatched(2));
            Assert.IsTrue(matching.Unmatched(0));
            Assert.IsTrue(matching.Unmatched(3));
        }
Example #2
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);
        }
Example #3
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);
        }