// 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; }
// 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 representativeA in _cuts[leftChild]) { // All representatives of the cut G[rightChild, V \ rightChild] foreach (BitSet representativeB 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(representativeB + _representative, leftChild, _graph); BitSet representativeA_ = _cuts[vg - leftChild].GetRepresentative(dna); // Find the representative Rb_ of the class [Ra ∪ Rw_]≡Vb_ DNeighborhood dnb = new DNeighborhood(representativeA + _representative, rightChild, _graph); BitSet representativeB_ = _cuts[vg - rightChild].GetRepresentative(dnb); // Find the representative Rw of the class [Ra ∪ Rb]≡Vw DNeighborhood dnw = new DNeighborhood(representativeA + representativeB, 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][representativeA, representativeA_]; int rightValue = _tables[rightChild][representativeB, representativeB_]; // 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); } } } }
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; }