[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)); }
/// <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); }
/// <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); }