コード例 #1
0
        public T Compute <T>(IDPAlgorithm <T> algorithm, TDNode parent, Dictionary <Tuple <TDNode, TDNode>, T> lookup)
        {
            T result;

            if (lookup.TryGetValue(Tuple.Create(this, parent), out result))
            {
                return(result);
            }

            IEnumerable <TDNode> children = Adj.Where((n) => n != parent);

            if (!children.Any())
            {
                result = algorithm.Introduce(this, Bag, algorithm.Leaf(ParentDecomposition.Width));
            }
            else
            {
                TDNode first = children.First();

                result = AdjustBag(algorithm, first, first.Compute(algorithm, this, lookup));

                foreach (TDNode next in children.Skip(1))
                {
                    result = algorithm.Join(this, result, AdjustBag(algorithm, next, next.Compute(algorithm, this, lookup)));
                }
            }

            // Only cache if the result might be reused, prevents caching in all nodes of a long chain
            if (parent == null || parent.Adj.Count() > 2)
            {
                lookup[Tuple.Create(this, parent)] = result;
            }

            return(result);
        }
コード例 #2
0
        public T Compute <T>(IDPAlgorithm <T> algorithm, TDNode parent)
        {
            VertexSubset.ClearLookup();

            // Note: through preprocessing, certain subtrees might have become empty. Do not consider.
            IEnumerable <TDNode> children = Adj.Where((n) => n != parent && n.Subtree.Any());

            if (children.Count() == 0)
            {
                return(algorithm.IntroduceEdges(algorithm.Introduce(this, Bag, algorithm.Leaf(ParentDecomposition.Width)), introduceEdges));
            }

            if (children.Count() == 1)
            {
                TDNode child = children.First();

                Vertex[] toForget    = child.Bag.Where((v) => !this.BagContains(v)).OrderBy((v) => v.Adj.Where((w) => BagContains(w.To)).Count()).Reverse().ToArray();
                Vertex[] toIntroduce = this.Bag.Where((v) => !child.BagContains(v)).ToArray();

                if (toIntroduce.Length > 0)
                {
                    return(algorithm.IntroduceEdges(algorithm.Introduce(this, toIntroduce, child.Compute(algorithm, this)), introduceEdges));
                }

                if (toForget.Length > 0)
                {
                    return(algorithm.IntroduceEdges(algorithm.Forget(this, toForget, child.Compute(algorithm, this)), introduceEdges));
                }

                // No change?
                return(algorithm.IntroduceEdges(child.Compute(algorithm, this), introduceEdges));
            }

            if (children.Count() > 2)
            {
                throw new Exception("TD not preprocessed!");
            }

            TDNode left = children.ElementAt(0), right = children.ElementAt(1);

            return(algorithm.IntroduceEdges(algorithm.Join(this, IntroduceIfNecessary(algorithm, left, left.Compute(algorithm, this)), IntroduceIfNecessary(algorithm, right, right.Compute(algorithm, this))), introduceEdges));
        }
コード例 #3
0
        public T IntroduceIfNecessary <T>(IDPAlgorithm <T> algorithm, TDNode child, T table)
        {
            Vertex[] toIntroduce = Bag.Where((v) => !child.BagContains(v)).ToArray();

            if (toIntroduce.Length > 0)
            {
                return(algorithm.Introduce(this, toIntroduce, table));
            }

            return(table);
        }
コード例 #4
0
        public T AdjustBag <T>(IDPAlgorithm <T> algorithm, TDNode child, T table)
        {
            Vertex[] toForget    = child.Bag.Where((v) => !this.BagContains(v)).ToArray();
            Vertex[] toIntroduce = Bag.Where((v) => !child.BagContains(v)).ToArray();

            if (toForget.Length > 0)
            {
                table = algorithm.Forget(this, toForget, table);
            }

            if (toIntroduce.Length > 0)
            {
                table = algorithm.Introduce(this, toIntroduce, table);
            }

            return(table);
        }