public Dictionary <int, Dictionary <PartialSolution, int> > Join(TDNode bag, Dictionary <int, Dictionary <PartialSolution, int> > left, Dictionary <int, Dictionary <PartialSolution, int> > right) { joinSW.Start(); Dictionary <int, Dictionary <PartialSolution, int> > result = new Dictionary <int, Dictionary <PartialSolution, int> >(); foreach (KeyValuePair <int, Dictionary <PartialSolution, int> > kvp in left) { Dictionary <PartialSolution, int> leftTable = kvp.Value; Dictionary <PartialSolution, int> rightTable = null; if (!right.TryGetValue(kvp.Key, out rightTable) || !leftTable.Any() || !rightTable.Any()) { continue; } List <int> verticesInvolved = new List <int>(); foreach (Vertex v in bag.Bag) { if ((leftTable.First().Key.Subset.LocalSubset & (1 << v.Color)) != 0) { verticesInvolved.Add(v.Color); } } Dictionary <PartialSolution, int> newTable; newTable = JoinTwo(bag, verticesInvolved, leftTable, rightTable); //newTable = JoinTwoIncremental(bag, verticesInvolved, leftTable, rightTable); if (newTable.Count > 0) { result[kvp.Key] = newTable; } } VertexSubset.ClearLookup(); joinSW.Stop(); Program.TableCount += result.Values.Sum((t) => t.Count); return(result); }
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)); }