// Given a vertex w, we can update the dNeighborhood of a set X to reflect the dNeighborhood of the set X + w in O(n) time public dNeighborhood CopyAndUpdate(Graph graph, int w) { // initialize an empty dNeighborhood in O(|Vector|) time dNeighborhood nx = new dNeighborhood(Vector); // Copy all values in O(|Vector|) time foreach (int v in Vector) nx.Occurrences[v] = Occurrences[v]; // Foreach vertex in N(w) * Vector they will appear one extra time in the multiset // This operation take O(n) time because of the bitset operation foreach (int v in graph.OpenNeighborhood(w) * Vector) nx.Occurrences[v] = Math.Min(dValue, nx.Occurrences[v] + 1); return nx; }
public dNeighborhood CopyAndUpdateVector(BitSet vector, bool increment) { // initialize an empty dNeighborhood in O(|Vector|) time dNeighborhood nx = new dNeighborhood(vector); BitSet iterateOver = increment ? Vector : vector; foreach (int v in iterateOver) nx.Occurrences[v] = Occurrences[v]; return nx; }
/*************************/ // Basic operations /*************************/ // When adding a new entry we check if the neighborhood is already contained in the set // If true, then we might replace the previous representative that is not connected to this neighborhood if the new one is lexicographically smaller public void Update(BitSet representative, dNeighborhood neighborhood) { Map.Add(representative.Copy(), neighborhood); }
// Returns the representative belonging to a given neighborhood public BitSet GetRepresentative(dNeighborhood neighborhood) { return Map.Reverse[neighborhood]; }
public bool ContainsNeighborhood(dNeighborhood neighborhood) { return Map.ContainsValue(neighborhood); }
// Recursively fills all tables for each node of the decomposition tree in a bottom up fashion // Node W is the current node we are working on private void FillTable(BitSet node) { // Initialize a new table of node W Tables[node] = new Table(); // All vertices of the graph BitSet VG = Graph.Vertices; int n = Graph.Size; // The base case for leaf nodes is handled seperately if (node.Count == 1) { FillLeaf(node); return; } // If the node has a size >1 then there it has child nodes BitSet leftChild = Tree.LeftChild[node]; BitSet rightChild = Tree.RightChild[node]; // We work in a bottom-up fashion, so we first recurse on the two children of this node // We know that this node is not a leaf since we already passed the check for leaf-nodes // We also know that this node has two children, since having 1 child in a boolean decomposition means that the parent and child node are the same and thus redundant FillTable(leftChild); FillTable(rightChild); // Initially set all combinations of representatives to the worst value, meaning that no solution exists foreach (BitSet representative in Cuts[node]) foreach (BitSet _representative in Cuts[VG - node]) Tables[node][representative, _representative] = Optimum.PessimalValue; // All representatives of the cut G[leftChild, V \ leftChild] foreach (BitSet representative_a in Cuts[leftChild]) { // All representatives of the cut G[rightChild, V \ rightChild] foreach (BitSet representative_b in Cuts[rightChild]) { // All representatives of the cut G[V \ node, node] foreach (BitSet _representative in Cuts[VG - node]) { // Find the representative Ra_ of the class [Rb ∪ Rw_]≡Va_ dNeighborhood dna = new dNeighborhood(representative_b + _representative, leftChild, Graph); BitSet _representative_a = Cuts[VG - leftChild].GetRepresentative(dna); // Find the representative Rb_ of the class [Ra ∪ Rw_]≡Vb_ dNeighborhood dnb = new dNeighborhood(representative_a + _representative, rightChild, Graph); BitSet _representative_b = Cuts[VG - rightChild].GetRepresentative(dnb); // Find the representative Rw of the class [Ra ∪ Rb]≡Vw dNeighborhood dnw = new dNeighborhood(representative_a + representative_b, VG - node, Graph); BitSet representative = Cuts[node].GetRepresentative(dnw); // Optimal size of this sigma,rho set in the left and right child int leftValue = Tables[leftChild][representative_a, _representative_a]; int rightValue = Tables[rightChild][representative_b, _representative_b]; // Some hoops to avoid integer overflowing int combination = leftValue == Optimum.PessimalValue || rightValue == Optimum.PessimalValue ? Optimum.PessimalValue : leftValue + rightValue; // Fill the optimal value that we can find in the current entry Tables[node][representative, _representative] = Optimum.Optimal(Tables[node][representative, _representative], combination); } } } }
// Implementation of Algorithm 1 of 'Fast dynamic programming for locally checkable vertex subset and vertex partitioning problems' (Bui-Xuan et al.) // Used to compute the representatives and their corresponding dNeighborhoods for a given node of the decomposition tree private void FillTable(Graph graph, BitSet cut) { int n = graph.Size; BitSet _cut = graph.Vertices - cut; // Lists of representatives that we keep track of on each level of the algorithm RepresentativeList representatives = new RepresentativeList(); RepresentativeList lastLevel = new RepresentativeList(); // Initial insertions, the empty set always has the empty neighborhood set as a representative initially dNeighborhood dInitial = new dNeighborhood(_cut); representatives.Update(new BitSet(0, n), dInitial); lastLevel.Update(new BitSet(0, n), dInitial); while (lastLevel.Count > 0) { RepresentativeList nextLevel = new RepresentativeList(); foreach (BitSet r in lastLevel) { foreach (int v in cut) { // avoid that r_ = r, since we already saved all sets of that size if (r.Contains(v)) continue; BitSet r_ = r + v; dNeighborhood dn = representatives.GetNeighborhood(r).CopyAndUpdate(graph, v); if (!representatives.ContainsNeighborhood(dn) && !dn.Equals(representatives.GetNeighborhood(r))) { nextLevel.Update(r_, dn); representatives.Update(r_, dn); } } } // Update the values for the next iteration lastLevel = nextLevel; } // Save the representatives at the current cut in the table Table[cut.Copy()] = representatives; // Save the maximum size that we encounter during all iterations; this will be the boolean dimension of the graph is d = 1. MaxDimension = Math.Max(MaxDimension, representatives.Count); }