Ejemplo n.º 1
0
        /// <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);
                }
            }
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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);
            }
        }
Ejemplo n.º 5
0
        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);
        }