public static PTD ExtendToPMC_Rule2(PTD Tau_wiggle, BitSet vNeighbors, ImmutableGraph graph) { BitSet bag = new BitSet(vNeighbors); List <PTD> children = new List <PTD>(Tau_wiggle.children); BitSet vertices = new BitSet(Tau_wiggle.vertices); vertices.UnionWith(vNeighbors); BitSet outlet = graph.Outlet(bag, vertices); BitSet inlet = new BitSet(vertices); inlet.ExceptWith(outlet); return(new PTD(bag, vertices, outlet, inlet, children)); }
public static PTD ExtendToPMC_Rule3(PTD Tau_wiggle, BitSet newRoot, ImmutableGraph graph) { Debug.Assert(newRoot.IsSupersetOf(Tau_wiggle.Bag)); BitSet bag = newRoot; BitSet vertices = new BitSet(Tau_wiggle.vertices); vertices.UnionWith(newRoot); List <PTD> children = new List <PTD>(Tau_wiggle.children); BitSet outlet = graph.Outlet(bag, vertices); BitSet inlet = new BitSet(vertices); inlet.ExceptWith(outlet); return(new PTD(bag, vertices, outlet, inlet, children)); }
/// <summary> /// a method extracted from the method above due to performance reasons. Read it as if the body of the method above would just continue here. /// </summary> /// <param name="Tau_prime">the ptdur</param> /// <param name="Tau">the ptd</param> /// <param name="graph">the underlying graph</param> /// <param name="result">the resulting ptd, or null if the return value is false</param> /// <param name="bag">the bag of the ptd to be</param> /// <returns>true, iff the resulting ptd is possibly usable</returns> private static bool AddPTDToPTDUR_CheckPossiblyUsable_CheckCliquish_Helper(PTD Tau_prime, PTD Tau, ImmutableGraph graph, out PTD result, BitSet bag, uint futureBagSize, int k, Graph mutableGraph) { List <PTD> children = new List <PTD>(Tau_prime.children); children.Add(Tau); // exit early if not possibly usable if (!IsPossiblyUsable(children, graph)) { result = null; return(false); } // if no vertices can be added to the bag due to size and the bag is not a pmc, we can reject this ptd immediately because it is not useful if (futureBagSize == k + 1 && !graph.IsPotMaxClique(bag)) { result = null; return(false); } if (!graph.IsCliquish(bag)) { result = null; return(false); } // if only one vertex can be added, determine all the candidates that would make this bag a pmc when added. If there are none, return. if (testIfAddingOneVertexToBagFormsPMC && futureBagSize == k) { // if bag is pmc already, we need this ptdur. (In that case no candidate exists which could be added.) if (!graph.IsPotMaxClique(bag)) { bool useless = true; foreach ((BitSet component, BitSet neighbor) in graph.ComponentsAndNeighbors(bag)) { // candidates are only found in full components if (neighbor.Equals(bag) && !component.Intersects(Tau_prime.vertices) && !component.Intersects(Tau.vertices)) { if (neighborsFirst) { onlyNeighborStopwatch.Start(); // test if a vertex in the bag has exactly one neighbor in this component, and the bag plus that vertex is still cliquish foreach (int v in bag.Elements()) { BitSet neighbors = new BitSet(graph.openNeighborhood[v]); neighbors.IntersectWith(component); if (neighbors.Count() == 1) { int candidate = neighbors.First(); bag[candidate] = true; if (graph.IsCliquish(bag)) // in this case it is guaranteed that the bag is also a pmc { Debug.Assert(graph.IsPotMaxClique(bag)); bag[candidate] = false; useless = false; break; } bag[candidate] = false; } } onlyNeighborStopwatch.Stop(); if (!useless) { break; } } articulationPointCandidatesStopwatch.Start(); // find articulation points within this component foreach (int articulationPoint in SafeSeparator.ArticulationPoints(mutableGraph, component)) { bag[articulationPoint] = true; if (graph.IsPotMaxClique(bag)) { bag[articulationPoint] = false; useless = false; break; } bag[articulationPoint] = false; } articulationPointCandidatesStopwatch.Stop(); if (!useless) { break; } if (!neighborsFirst) { onlyNeighborStopwatch.Start(); // test if a vertex in the bag has exactly one neighbor in this component, and the bag plus that vertex is still cliquish foreach (int v in bag.Elements()) { BitSet neighbors = new BitSet(graph.openNeighborhood[v]); neighbors.IntersectWith(component); if (neighbors.Count() == 1) { int candidate = neighbors.First(); bag[candidate] = true; if (graph.IsCliquish(bag)) // in this case it is guaranteed that the bag is also a pmc { Debug.Assert(graph.IsPotMaxClique(bag)); bag[candidate] = false; useless = false; break; } bag[candidate] = false; } } onlyNeighborStopwatch.Stop(); if (!useless) { break; } } // TODO: possibly exclude candidates that are in this ptdur's inlet? Is that correct? } } if (useless) { result = null; return(false); } } } // usability is established, so we build the ptd BitSet vertices = new BitSet(Tau_prime.vertices); vertices.UnionWith(Tau.vertices); BitSet outlet = graph.Outlet(bag, vertices); BitSet inlet = new BitSet(vertices); inlet.ExceptWith(outlet); result = new PTD(new BitSet(bag), vertices, outlet, inlet, children); return(true); }