public void IntroduceLate(TDNode parent) { foreach (TDNode n in Adj) { if (n != parent) { n.IntroduceLate(this); } } for (int i = 0; i < OptimizedBag.Length; i++) { Vertex v = OptimizedBag[i]; // Check if v is introduced if (Adj.Any((n) => n != parent && n.BagContains(v))) { continue; } // Must introduce before forgetting if (!parent.BagContains(v)) { continue; } // v is not introduced, check if we can delay if (v.Adj.Any((e) => { Vertex w = e.To; return(BagContains(w) && !parent.BagContains(w)); })) { continue; } // Delay introduction, remove v from bag OptimizedBag[i] = null; OptimizedByColor[v.Color] = null; } OptimizedBag = OptimizedBag.Where((v) => v != null).ToArray(); }
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); }
// Adds a forget bag before any introduce public void ForgetBeforeIntroduce(TDNode parent) { IEnumerable <TDNode> children = Adj.Where((n) => n != parent); if (children.Count() == 1) { TDNode child = children.First(); IEnumerable <Vertex> toForget = child.Bag.Where((v) => !this.BagContains(v)); IEnumerable <Vertex> toIntroduce = this.Bag.Where((v) => !child.BagContains(v)); if (toForget.Any() && toIntroduce.Any()) { TDNode newNode = new TDNode(0, ParentDecomposition, VertexByColor.Length); newNode.Bag = child.Bag.Where((v) => this.BagContains(v)).ToArray(); foreach (Vertex v in newNode.Bag) { newNode.VertexByColor[v.Color] = v; } this.Adj.Remove(child); this.Adj.Add(newNode); child.Adj.Remove(this); child.Adj.Add(newNode); newNode.Adj.Add(child); newNode.Adj.Add(this); ParentDecomposition.Nodes.Add(newNode); newNode.ForgetBeforeIntroduce(this); return; } child.ForgetBeforeIntroduce(this); return; } foreach (TDNode child in children) { child.ForgetBeforeIntroduce(this); } }
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)); }