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); }
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)); }