/// <summary> /// Updates the vertex-set and the width properties of all ancestors of a node in a bottom-up fashion, until the given ancestor is reached. /// </summary> /// <param name="child">A descendant of all nodes that will be updated.</param> /// <param name="end">The updating of the ancestor will stop once this node is reach. The end-node itself will not be updated.</param> /// <param name="add">The vertices that will be added to the vertex-set of the ancestors. NULL can be passed if no vertices should be added.</param> /// <param name="remove">The vertices that will be removed from the vertex-set of the ancestors. NULL can be passed if no vertices should be removed.</param> protected void updateAncestors(DecompositionNode child, DecompositionNode end, BitSet add, BitSet remove) { bool addToVertexSet = add != null && !add.IsEmpty; bool removeFromVertexSet = remove != null && !remove.IsEmpty; for (DecompositionNode ancestor = child?.Parent; ancestor != end && ancestor != null; child = ancestor, ancestor = ancestor.Parent) { if (addToVertexSet || removeFromVertexSet) { if (addToVertexSet) { ancestor.Set.Or(add); } if (removeFromVertexSet) { ancestor.Set.Exclude(remove); } ancestor.UpdateWidthProperties(); } else { ancestor.UpdateWidthProperties(false); } } }
protected DecompositionNode backtrack(DecompositionTree tree, DecompositionNode[] leaves, double[,] width, BitSet[,] sets, int index, int size, ref int treeindex) { if (size == 1) { DecompositionNode node = new DecompositionNode(leaves[index], tree); node.Index = index; tree.Nodes[index] = node; return(node); } DecompositionNode parent = new DecompositionNode(sets[index, size], treeindex--, tree); tree.Nodes[parent.Index] = parent; int split = -1; double splitwidth = double.PositiveInfinity; for (int i = index + 1; i < index + size; i++) { double max = Math.Max(width[index, i - index], width[i, size - (i - index)]); if (max <= splitwidth) { splitwidth = max; split = i; } } DecompositionNode left = this.backtrack(tree, leaves, width, sets, index, split - index, ref treeindex); DecompositionNode right = this.backtrack(tree, leaves, width, sets, split, size - (split - index), ref treeindex); tree.Attach(parent, left, Branch.Left); tree.Attach(parent, right, Branch.Right); tree.Attach(null, parent, Branch.Left); parent.UpdateWidthProperties(false); return(parent); }
private void updateTree(DecompositionNode a, DecompositionNode b) { DecompositionNode oldParentA = a.Parent; Branch oldBranchA = a.Branch; DecompositionNode oldParentB = b.Parent; Branch oldBranchB = b.Branch; // Find the first common ancestor of a and b. DecompositionNode common = this.findCommonAncestor(a, b); // Swap position of the subtrees. this.Tree.Attach(oldParentA, b, oldBranchA); this.Tree.Attach(oldParentB, a, oldBranchB); // Update the ancestors of a up to the common ancestor. this.updateAncestors(a, common, a.Set, b.Set); // Update the ancestors of b up to the common ancestor. this.updateAncestors(b, common, b.Set, a.Set); // Update the first common ancestor. common.UpdateWidthProperties(false); // Update the remaining common ancestors. this.updateAncestors(common, null, null, null); }
/// <summary> /// Adds the vertex as leaf to the partial tree. /// </summary> /// <param name="tree">The partial tree.</param> /// <param name="vertex">The vertex that will be added.</param> /// <param name="index">The index of the vertex in the tree.</param> protected void add(DecompositionTree tree, Vertex vertex, int index) { // Create the child node. DecompositionNode child = new DecompositionNode(vertex, index, tree); tree.Nodes[index] = child; if (tree.Root == null) { tree.Attach(null, child, Branch.Left); } else { BitSet set = new BitSet(tree.Root.Set); set[vertex.Index] = true; DecompositionNode parent = new DecompositionNode(set, index + 1, tree); tree.Nodes[index + 1] = parent; tree.Attach(parent, tree.Root, Branch.Right); tree.Attach(parent, child, Branch.Left); tree.Attach(null, parent, Branch.Left); parent.UpdateWidthProperties(false); } }
private void updateTree(DecompositionNode oldsibling, DecompositionNode newsibling) { DecompositionNode grandparent = this.SelectedNode.Parent.Parent; Branch parentbranch = this.SelectedNode.Parent.Branch; // connect parent to parent of new sibling this.Tree.Attach(newsibling.Parent, this.SelectedNode.Parent, newsibling.Branch); // connect new sibling to parent this.Tree.Attach(this.SelectedNode.Parent, newsibling, oldsibling.Branch); // connect old sibling to grandparent this.Tree.Attach(grandparent, oldsibling, parentbranch); // update the sets and width properties DecompositionNode common = null; if (!this.SelectedNode.Parent.Set.Intersects(newsibling.Set)) { // parent this.SelectedNode.Parent.Set = this.SelectedNode.Set | newsibling.Set; this.SelectedNode.Parent.UpdateWidthProperties(); // the common ancestor common = this.findCommonAncestor(this.SelectedNode.Parent, oldsibling.Parent); // ancestors of parent this.updateAncestors(this.SelectedNode.Parent, common, this.SelectedNode.Set, null); // ancestors of the old sibling this.updateAncestors(oldsibling, common, null, this.SelectedNode.Set); common.UpdateWidthProperties(false); } else if (this.SelectedNode.Set.IsSubsetOf(newsibling.Set)) { // the common ancestor common = this.SelectedNode.Parent; // ancestors of oldsibling this.updateAncestors(oldsibling, common, null, this.SelectedNode.Set); // parent this.SelectedNode.Parent.Set = this.SelectedNode.Set | newsibling.Set; this.SelectedNode.Parent.UpdateWidthProperties(); } else // the new sibling is a descendant of the original sibling { // parent this.SelectedNode.Parent.Set = this.SelectedNode.Set | newsibling.Set; this.SelectedNode.Parent.UpdateWidthProperties(); // the common ancestor common = oldsibling.Parent; // ancestors of the new sibling this.updateAncestors(this.SelectedNode.Parent, common, this.SelectedNode.Set, null); if (common != null) { common.UpdateWidthProperties(false); } } this.updateAncestors(common, null, null, null); }