Exemplo 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);
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Computes the maximum width and the sum of widths of the nodes of the subtree ...
        /// </summary>
        /// <param name="child">The node whose subtree has already been computed.</param>
        /// <param name="end">The parent of the root of the subtree that we want to compute.</param>
        /// <param name="add">he 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>
        /// <param name="maximum">The maximum width of the subtree, excluding the width of the subtree rooted at the child.</param>
        /// <param name="sum">The sum of the width of the nodes of the subtree, excluding the sum of the subtree rooted at the child.</param>
        protected void computeWidthAncestors(DecompositionNode child, DecompositionNode end, BitSet add, BitSet remove, ref double maximum, ref double sum)
        {
            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)
            {
                double width = ancestor.Width;
                if (addToVertexSet || removeFromVertexSet)
                {
                    BitSet set = new BitSet(ancestor.Set);
                    if (addToVertexSet)
                    {
                        set.Or(add);
                    }
                    if (removeFromVertexSet)
                    {
                        set.Exclude(remove);
                    }
                    width = this.Tree.WidthParameter.GetWidth(this.Tree.Graph, set);
                }
                maximum = Math.Max(maximum, Math.Max(width, child.Sibling.SubTreeWidth));
                sum    += width + child.Sibling.SubTreeSum;
            }
        }
Exemplo n.º 3
0
        protected override double computeCost()
        {
            double maximum = Math.Max(this.SelectedNodeLeft.SubTreeWidth, this.SelectedNodeRight.SubTreeWidth),
                   sum     = this.SelectedNodeLeft.SubTreeSum + this.SelectedNodeRight.SubTreeSum;

            // Find the first common ancestor of a and b.
            DecompositionNode common = this.findCommonAncestor(this.SelectedNodeLeft, this.SelectedNodeRight);

            // Compute the width of the ancestors of a up to the common ancestor.
            this.computeWidthAncestors(this.SelectedNodeLeft, common, this.SelectedNodeRight.Set, this.SelectedNodeLeft.Set, ref maximum, ref sum);
            // Compute the width of the ancestors of b up to the common ancestor.
            this.computeWidthAncestors(this.SelectedNodeRight, common, this.SelectedNodeLeft.Set, this.SelectedNodeRight.Set, ref maximum, ref sum);

            // Compute the width of the first common ancestor.
            if (maximum < common.Width)
            {
                maximum = common.Width;
            }
            sum += common.Width;

            // Compute the width of the remaining common ancestors.
            this.computeWidthAncestors(common, null, null, null, ref maximum, ref sum);

            double topwidth = this.Tree.Root.Right.Width;

            if (common.IsRoot)
            {
                BitSet set = this.Tree.Root.Right.Set - this.SelectedNodeRight.Set | this.SelectedNodeLeft.Set;
                topwidth = this.Tree.WidthParameter.GetWidth(this.Tree.Graph, set);
            }

            return(DecompositionTree.ComputeCost(maximum, this.Tree.VertexCount, sum, topwidth));
        }
Exemplo n.º 4
0
 /// <summary>
 /// Searches for the first common ancestor of two nodes.
 /// </summary>
 /// <param name="n1">One of the nodes.</param>
 /// <param name="n2">The other node.</param>
 /// <returns>The common ancestor.</returns>
 protected DecompositionNode findCommonAncestor(DecompositionNode n1, DecompositionNode n2)
 {
     for (DecompositionNode ancestor = n1; ancestor != null; ancestor = ancestor.Parent)
     {
         if (ancestor.Set.IsSupersetOf(n2.Set))
         {
             return(ancestor);
         }
     }
     throw new KeyNotFoundException();
 }
Exemplo n.º 5
0
        public override LocalSearchOperation GetRandomOperation(DecompositionTree tree, Random rng)
        {
            // No operations available.
            if (tree.Nodes.Length <= 3)
            {
                return(null);
            }

            // Select a random node that will be moved to a different position in the tree.
            int index = this.getRandomNonRootIndex(tree, rng);
            DecompositionNode selected = tree.Find(index);

            // Select a random node that will become the new sibling of the selected node.
            int candidateCount = tree.Nodes.Length - selected.SubTreeSize - 2,
                positionIndex  = 1 + rng.Next(candidateCount);

            // We need to ensure that we do not select a node in the subtree of the selected node, nor its current parent and sibling.
            if (selected.Branch == Branch.Left)
            {
                // Shift it outside the range of the subtree of the selected node.
                if (index - selected.SubTreeSize < positionIndex && positionIndex <= index)
                {
                    positionIndex += selected.SubTreeSize;
                }
                // Shift it past the sibling and the parent of the selected node.
                if (positionIndex == index + selected.Sibling.SubTreeSize)
                {
                    positionIndex += 2;
                }
                // Shift it past the parent of the selected node.
                else if (positionIndex == index + selected.Sibling.SubTreeSize + 1)
                {
                    positionIndex++;
                }
            }
            else
            {
                // Shift it past the sibling of the selected node.
                if (positionIndex == index - selected.SubTreeSize)
                {
                    positionIndex++;
                }
                // Shift it past the parent and outside the range of the subtree of the selected node.
                if (index - selected.SubTreeSize < positionIndex && positionIndex <= index + 1)
                {
                    positionIndex += selected.SubTreeSize + 1;
                }
            }
            DecompositionNode sibling = tree.Find(positionIndex);

            return(new MoveOperation(tree, selected, sibling));
        }
        public override DecompositionTree Construct(Graph graph, WidthParameter widthparameter)
        {
            DecompositionTree tree = new DecompositionTree(graph, widthparameter);

            // Create the leaves.
            DecompositionNode[] nodes = new DecompositionNode[graph.Vertices.Count];
            for (int i = 0; i < nodes.Length; i++)
            {
                tree.Nodes[i] = nodes[i] = new DecompositionNode(new BitSet(nodes.Length, graph.Vertices[i].Index), i, tree);
            }

            int size = nodes.Length;

            while (size > 1)
            {
                // Find the pair of nodes whose combination is of minimal width.
                double min = double.PositiveInfinity;
                int    first = -1, second = -1;
                for (int i = 0; i < size; i++)
                {
                    for (int j = i + 1; j < size; j++)
                    {
                        double width = widthparameter.GetWidth(graph, nodes[i].Set | nodes[j].Set);
                        if (width < min)
                        {
                            min    = width;
                            first  = i;
                            second = j;
                        }
                    }
                }
                // Create the parent and connect it to its children.
                DecompositionNode node = new DecompositionNode(nodes[first].Set | nodes[second].Set, nodes.Length * 2 - size, tree);
                tree.Attach(node, nodes[first], Branch.Left);
                tree.Attach(node, nodes[second], Branch.Right);
                tree.Nodes[node.Index] = node;

                // Update the active set of nodes.
                nodes[first]  = node;
                nodes[second] = nodes[size - 1];

                size--;
            }

            tree.Attach(null, nodes[0], Branch.Left);
            tree.ComputeWidth();
            return(tree);
        }
Exemplo n.º 7
0
        public override DecompositionTree Construct(Graph graph, WidthParameter widthparameter)
        {
            DecompositionTree tree = new DecompositionTree(graph, widthparameter);

            // Create the leaves.
            DecompositionNode[] nodes = new DecompositionNode[graph.Vertices.Count];
            for (int i = 0; i < nodes.Length; i++)
            {
                tree.Nodes[i] = nodes[i] = new DecompositionNode(new BitSet(nodes.Length, graph.Vertices[i].Index), i, tree);
            }

            int size = nodes.Length;

            while (size > 1)
            {
                int first  = this.rng.Next(size);
                int second = this.rng.Next(size - 1);
                if (second <= first)
                {
                    second++;
                }

                // Create the parent and connect it to its children.
                DecompositionNode node = new DecompositionNode(nodes[first].Set | nodes[second].Set, nodes.Length * 2 - size, tree);
                tree.Attach(node, nodes[first], Branch.Left);
                tree.Attach(node, nodes[second], Branch.Right);
                tree.Nodes[node.Index] = node;

                // Update the active set of nodes.
                nodes[first]  = node;
                nodes[second] = nodes[size - 1];

                size--;
            }

            tree.Attach(null, nodes[0], Branch.Left);
            tree.ComputeWidth();
            return(tree);
        }
Exemplo n.º 8
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);
        }
Exemplo n.º 9
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);
            }
        }
Exemplo n.º 11
0
        public override IEnumerable <LocalSearchOperation> Operations(DecompositionTree tree, Random rng)
        {
            int[] combinationcounters = new int[tree.Nodes.Length];
            DecompositionNode[]   leftcandidates = new DecompositionNode[tree.Nodes.Length];
            DecompositionNode[][] rightcandidates = new DecompositionNode[tree.Nodes.Length][];
            DecompositionNode     left = null, right = null;

            int leftindex = 0, total = 0;

            foreach (var node in tree.Root.SubTree(TreeTraversal.ParentFirst))
            {
                leftcandidates[leftindex]      = node;
                combinationcounters[leftindex] = tree.Nodes.Length - node.SubTreeSize - 1;
                for (DecompositionNode ancestor = node.Parent; ancestor != null; ancestor = ancestor.Parent)
                {
                    combinationcounters[leftindex]--;
                }
                total += combinationcounters[leftindex];
                leftindex++;
            }

            int maximum = tree.Nodes.Length;

            // As long as there is a operation possible
            while (total > 0)
            {
                int sample = rng.Next(total) + 1, sum = 0;
                // Find a random left candidate.
                for (leftindex = 0; leftindex < maximum; leftindex++)
                {
                    // Move invalid left candidates to the back.
                    while (combinationcounters[leftindex] == 0)
                    {
                        maximum--;
                        combinationcounters[leftindex] = combinationcounters[maximum];
                        leftcandidates[leftindex]      = leftcandidates[maximum];
                        rightcandidates[leftindex]     = rightcandidates[maximum];
                        if (maximum == leftindex)
                        {
                            break;
                        }
                    }

                    sum += combinationcounters[leftindex];
                    if (sample <= sum)
                    {
                        if (combinationcounters[leftindex] == 0)
                        {
                            throw new InvalidOperationException();
                        }

                        // Select the random left candidate.
                        left = leftcandidates[leftindex];

                        DecompositionNode[] candidates = rightcandidates[leftindex];
                        if (candidates == null)
                        {
                            // Initialize the set of all right candidates.
                            candidates = rightcandidates[leftindex] = new DecompositionNode[combinationcounters[leftindex]];
                            int index = 0;

                            foreach (DecompositionNode node in left.Sibling.SubTree(TreeTraversal.ParentFirst).Skip(1))
                            {
                                candidates[index++] = node;
                            }
                            for (DecompositionNode ancestor = left.Parent; !ancestor.IsRoot; ancestor = ancestor.Parent)
                            {
                                foreach (DecompositionNode node in ancestor.Sibling.SubTree(TreeTraversal.ParentFirst))
                                {
                                    candidates[index++] = node;
                                }
                            }
                        }

                        // Select a random position.
                        int positionindex = rng.Next(combinationcounters[leftindex]);
                        right = candidates[positionindex];
                        candidates[positionindex] = candidates[--combinationcounters[leftindex]];
                        total--;
                        break;
                    }
                }

                if (right == null)
                {
                    throw new InvalidOperationException();
                }

                yield return(new SwapOperation(tree, left, right));
            }
        }
        public override DecompositionTree Construct(Graph graph, WidthParameter widthparameter)
        {
            int index = 0;
            DecompositionTree tree = new DecompositionTree(graph, widthparameter);
            DecompositionNode root = new DecompositionNode(~(new BitSet(tree.VertexCount)), index, tree);

            tree.Nodes[index++] = root;
            tree.Attach(null, root, Branch.Left);

            List <DecompositionNode> candidates = new List <DecompositionNode>();

            candidates.Add(root);

            while (candidates.Count > 0)
            {
                // Select a random childless internal node.
                DecompositionNode parent = candidates[this.rng.Next(candidates.Count)];
                candidates.Remove(parent);

                // Shuffle its set of vertices.
                int[] indices = parent.Set.ToArray();
                indices.Shuffle(this.rng);

                // Split the set randomly into two non-empty sets.
                int split = 1 + this.rng.Next(indices.Length - 2);

                // Create its children.
                DecompositionNode left = null;
                if (split == 1)
                {
                    left = new DecompositionNode(graph.Vertices[indices[0]], index, tree);
                }
                else
                {
                    BitSet leftset = new BitSet(tree.VertexCount);
                    for (int i = 0; i < split; i++)
                    {
                        leftset[indices[i]] = true;
                    }
                    left = new DecompositionNode(leftset, index, tree);
                    candidates.Add(left);
                }
                tree.Nodes[index++] = left;
                tree.Attach(parent, left, Branch.Left);

                DecompositionNode right = null;
                if (split == indices.Length - 1)
                {
                    right = new DecompositionNode(graph.Vertices[indices[indices.Length - 1]], index, tree);
                }
                else
                {
                    BitSet rightset = new BitSet(tree.VertexCount);
                    for (int i = split; i < indices.Length; i++)
                    {
                        rightset[indices[i]] = true;
                    }
                    right = new DecompositionNode(rightset, index, tree);
                    candidates.Add(right);
                }
                tree.Nodes[index++] = right;
                tree.Attach(parent, right, Branch.Right);
            }

            tree.ComputeWidth();
            return(tree);
        }
Exemplo n.º 13
0
 public MoveOperation(DecompositionTree tree, DecompositionNode node, DecompositionNode sibling) : base(tree)
 {
     this.SelectedNode    = node;
     this.SelectedSibling = sibling;
     this.OriginalSibling = node.Sibling;
 }
Exemplo n.º 14
0
 public SwapOperation(DecompositionTree tree, DecompositionNode left, DecompositionNode right) : base(tree)
 {
     this.SelectedNodeLeft  = left;
     this.SelectedNodeRight = right;
 }
Exemplo n.º 15
0
        protected override double computeCost()
        {
            double maximum           = this.SelectedNode.SubTreeWidth,
                   sum               = this.SelectedNode.SubTreeSum,
                   topwidth          = this.Tree.Root.Right.Width;
            DecompositionNode common = null;

            if (!this.SelectedNode.Parent.Set.Intersects(this.SelectedSibling.Set))
            {
                maximum = Math.Max(maximum, Math.Max(this.SelectedSibling.SubTreeWidth, this.OriginalSibling.SubTreeWidth));
                sum    += this.SelectedSibling.SubTreeSum + this.OriginalSibling.SubTreeSum;

                // parent
                double width = this.Tree.WidthParameter.GetWidth(this.Tree.Graph, this.SelectedNode.Set | this.SelectedSibling.Set);
                sum += width;
                if (width > maximum)
                {
                    maximum = width;
                }

                // the common ancestor
                common = this.findCommonAncestor(this.SelectedNode.Parent, this.SelectedSibling);
                sum   += common.Width;
                if (maximum < common.Width)
                {
                    maximum = common.Width;
                }

                // update the width of the child of the root
                if (common.IsRoot)
                {
                    BitSet set = this.Tree.Root.Right.Set;
                    if (set.IsSupersetOf(this.SelectedNode.Set))
                    {
                        set -= this.SelectedNode.Set;
                    }
                    else
                    {
                        set |= this.SelectedNode.Set;
                    }
                    topwidth = this.Tree.WidthParameter.GetWidth(this.Tree.Graph, set);
                }

                // ancestors of parent
                this.computeWidthAncestors(this.SelectedNode.Parent, common, null, this.SelectedNode.Set, ref maximum, ref sum);
                // ancestors of the new sibling
                this.computeWidthAncestors(this.SelectedSibling, common, this.SelectedNode.Set, null, ref maximum, ref sum);
            }
            else if (this.SelectedNode.Set.IsSubsetOf(this.SelectedSibling.Set))
            {
                sum += this.OriginalSibling.SubTreeSum;
                if (maximum < this.OriginalSibling.SubTreeWidth)
                {
                    maximum = this.OriginalSibling.SubTreeWidth;
                }

                // parent
                sum += this.SelectedSibling.Width;
                if (maximum < this.SelectedSibling.Width)
                {
                    maximum = this.SelectedSibling.Width;
                }

                // the common ancestor
                common = this.SelectedSibling;

                // update the width of the child of the root.
                if (this.SelectedSibling.IsRoot)
                {
                    topwidth = this.SelectedNode.Width;
                }

                // ancestors of parent
                this.computeWidthAncestors(this.SelectedNode.Parent, this.SelectedSibling.Parent, null, this.SelectedNode.Set, ref maximum, ref sum);
            }
            else // the new sibling is a descendant of the original sibling
            {
                sum += this.SelectedSibling.SubTreeSum;
                if (maximum < this.SelectedSibling.SubTreeWidth)
                {
                    maximum = this.SelectedSibling.SubTreeWidth;
                }

                // parent
                double width = this.Tree.WidthParameter.GetWidth(this.Tree.Graph, this.SelectedNode.Set | this.SelectedSibling.Set);
                sum += width;
                if (maximum < width)
                {
                    maximum = width;
                }

                // the common ancestor
                common = this.SelectedNode.Parent;

                // update the width of the child of the root.
                if (this.SelectedNode.Parent.IsRoot)
                {
                    topwidth = this.OriginalSibling.Right.Set.IsSupersetOf(this.SelectedSibling.Set) ? this.OriginalSibling.Left.Width : this.OriginalSibling.Right.Width;
                }

                // ancestors of the new sibling
                this.computeWidthAncestors(this.SelectedSibling, this.SelectedNode.Parent, this.SelectedNode.Set, null, ref maximum, ref sum);
            }

            // common ancestors
            this.computeWidthAncestors(common, null, null, null, ref maximum, ref sum);

            return(DecompositionTree.ComputeCost(maximum, this.Tree.VertexCount, sum, topwidth));
        }
Exemplo n.º 16
0
        // Get all operations in random order.
        public override IEnumerable <LocalSearchOperation> Operations(DecompositionTree tree, Random rng)
        {
            // Initialize the insertion candidate list
            int[] candidatecounters = new int[tree.Nodes.Length];
            DecompositionNode[]   insertioncandidates = new DecompositionNode[tree.Nodes.Length];
            DecompositionNode[][] positioncandidates = new DecompositionNode[tree.Nodes.Length][];
            DecompositionNode     insertioncandidate = null, positioncandidate = null;

            int candidateindex = 0, total = 0;

            foreach (var node in tree.Root.SubTree(TreeTraversal.ParentFirst))
            {
                insertioncandidates[candidateindex] = node;
                total += candidatecounters[candidateindex] = tree.Nodes.Length - node.SubTreeSize - 2;
                candidateindex++;
            }

            int maximum = tree.Nodes.Length;

            // As long as there is a operation possible
            while (total > 0)
            {
                int sample = rng.Next(total) + 1, sum = 0;
                // Find a random insertion candidate.
                for (candidateindex = 0; candidateindex < maximum; candidateindex++)
                {
                    // Move invalid insertion candidates to the back.
                    while (candidatecounters[candidateindex] == 0)
                    {
                        maximum--;
                        candidatecounters[candidateindex]   = candidatecounters[maximum];
                        insertioncandidates[candidateindex] = insertioncandidates[maximum];
                        positioncandidates[candidateindex]  = positioncandidates[maximum];
                        if (maximum == candidateindex)
                        {
                            break;
                        }
                    }

                    sum += candidatecounters[candidateindex];
                    if (sample <= sum)
                    {
                        if (candidatecounters[candidateindex] == 0)
                        {
                            throw new InvalidOperationException();
                        }

                        // Select the random insertion candidate.
                        insertioncandidate = insertioncandidates[candidateindex];

                        DecompositionNode[] positions = positioncandidates[candidateindex];
                        if (positions == null)
                        {
                            // Initialize the set of all candidate positions.
                            positions = positioncandidates[candidateindex] = new DecompositionNode[candidatecounters[candidateindex]];
                            int index = 0;
                            foreach (var node in insertioncandidate.Sibling.SubTree(TreeTraversal.ParentFirst).Skip(1))
                            {
                                positions[index++] = node;
                            }
                            for (DecompositionNode ancestor = insertioncandidate.Parent; !ancestor.IsRoot; ancestor = ancestor.Parent)
                            {
                                foreach (DecompositionNode node in ancestor.Sibling.SubTree(TreeTraversal.ParentFirst))
                                {
                                    positions[index++] = node;
                                }
                                if (ancestor != insertioncandidate.Parent)
                                {
                                    positions[index++] = ancestor;
                                }
                            }
                            if (!insertioncandidate.Parent.IsRoot)
                            {
                                positions[index++] = tree.Root;
                            }
                        }

                        // Select a random position.
                        int positionindex = rng.Next(candidatecounters[candidateindex]);
                        positioncandidate        = positions[positionindex];
                        positions[positionindex] = positions[--candidatecounters[candidateindex]];
                        total--;
                        break;
                    }
                }

                if (positioncandidate == null)
                {
                    throw new InvalidOperationException();
                }

                yield return(new MoveOperation(tree, insertioncandidate, positioncandidate));
            }
        }
Exemplo n.º 17
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);
        }