public Dictionary <int, Dictionary <PartialSolution, int> > Forget(TDNode bag, Vertex[] vertices, Dictionary <int, Dictionary <PartialSolution, int> > table) { forgetSW.Start(); Dictionary <int, Dictionary <PartialSolution, int> > result = new Dictionary <int, Dictionary <PartialSolution, int> >(); int vertexMask = 0; foreach (Vertex v in vertices) { vertexMask |= (1 << v.Color); } byte[] tempUF = new byte[bag.ParentDecomposition.Width]; foreach (KeyValuePair <int, Dictionary <PartialSolution, int> > kvp in table) { int subset = kvp.Key; int newSubset = subset & ~vertexMask; Dictionary <PartialSolution, int> newDict = null; if (!result.TryGetValue(newSubset, out newDict)) { newDict = new Dictionary <PartialSolution, int>(); result.Add(newSubset, newDict); } foreach (KeyValuePair <PartialSolution, int> kvp2 in kvp.Value) { if (kvp2.Key.CountComponents() != kvp2.Key.CountComponents(newSubset)) { continue; // Check whether set remains connected } VertexSubset newVertexSubset = VertexSubset.Create(bag, newSubset, kvp2.Key.Subset, null); PartialSolution newPs = new PartialSolution(newVertexSubset, kvp2.Key); Upsert(newDict, newPs, kvp2.Value); } } foreach (KeyValuePair <int, Dictionary <PartialSolution, int> > kvp in table.ToList()) { table[kvp.Key] = RankBased.Reduce(kvp.Value, 0.125); } forgetSW.Stop(); Program.TableCount += result.Values.Sum((t) => t.Count); return(result); }
// Joins two tables that have partial solutions with one type of vertex subset public Dictionary <PartialSolution, int> JoinTwo(TDNode bag, List <int> verticesInvolved, Dictionary <PartialSolution, int> leftTable, Dictionary <PartialSolution, int> rightTable) { Dictionary <PartialSolution, int> newTable = new Dictionary <PartialSolution, int>(); // Reducing before Join is almost certainly beneficial, use a low threshold leftTable = RankBased.Reduce(leftTable, 0.999); rightTable = RankBased.Reduce(rightTable, 0.999); KeyValuePair <PartialSolution, int>[] rightCopy = rightTable.ToArray(); foreach (KeyValuePair <PartialSolution, int> leftSol in leftTable) { foreach (KeyValuePair <PartialSolution, int> rightSol in rightCopy) { VertexSubset newSubset = VertexSubset.Create(bag, leftSol.Key.Subset.LocalSubset, leftSol.Key.Subset, rightSol.Key.Subset); PartialSolution newSol = new PartialSolution(newSubset, leftSol.Key); bool good = true; foreach (int i in verticesInvolved) { byte rep = rightSol.Key.Find(i); if (rep == i) { continue; } if (newSol.Find(i) == newSol.Find(rep)) { good = false; break; } newSol.Union(i, rep); } if (good) { Upsert(newTable, newSol, leftSol.Value + rightSol.Value); } } } // Do not call reduce here: the forget, introduce or join bag that comes next will take care of it //newTable = RankBased.Reduce(newTable, 0.5); return(newTable); }
public Dictionary <int, Dictionary <PartialSolution, int> > Introduce(TDNode bag, Vertex[] vertices, Dictionary <int, Dictionary <PartialSolution, int> > table) { introSW.Start(); Vertex[] terminals = vertices.Where((v) => v.IsTerminal).ToArray(); Vertex[] nonterminals = vertices.Where((v) => !v.IsTerminal).ToArray(); Dictionary <int, Dictionary <PartialSolution, int> > result = new Dictionary <int, Dictionary <PartialSolution, int> >(); for (int i = 0; i < (1 << nonterminals.Length); i++) { List <Vertex> toAdd = new List <Vertex>(terminals.Length + i.BitCount()); foreach (Vertex v in terminals) { toAdd.Add(v); } for (int j = 0; j < nonterminals.Length; j++) { if ((i & (1 << j)) != 0) { toAdd.Add(nonterminals[j]); } } int addMask = 0; foreach (Vertex v in toAdd) { addMask |= (1 << v.Color); } List <Edge> introEdges = new List <Edge>(); foreach (Vertex v in toAdd) { foreach (Edge e in v.Adj) { if (bag.Bag.Contains(e.To) && !introEdges.Contains(e)) { introEdges.Add(e); } } } foreach (KeyValuePair <int, Dictionary <PartialSolution, int> > kvp in table) { int subset = kvp.Key; int newSubset = subset | addMask; Dictionary <PartialSolution, int> newDict = new Dictionary <PartialSolution, int>(); Dictionary <PartialSolution, int> localTable = RankBased.Reduce(kvp.Value, 0.999); foreach (KeyValuePair <PartialSolution, int> kvp2 in localTable) { VertexSubset newVertexSubset = VertexSubset.Create(bag, newSubset, kvp2.Key.Subset, null); newDict.Add(new PartialSolution(newVertexSubset, kvp2.Key), kvp2.Value); } if (introEdges.Where((e) => (newSubset & (1 << e.To.Color)) != 0).Count() > 2) { // Efficient method of introducing multiple edges at once and simultaneously running RankBased Reduce //newDict = IntroduceEdgesIntoTable(newDict, introEdges.Where((e) => (newSubset & (1 << e.To.Color)) != 0).ToArray()); newDict = IntroduceEdgesIntoTable(newDict, introEdges.Where((e) => (newSubset & (1 << e.To.Color)) != 0).ToArray()); } else { foreach (Edge e in introEdges) { if ((newSubset & (1 << e.To.Color)) != 0) { newDict = RankBased.Reduce(IntroduceEdge(newDict, e), 0.125); } } } if (newDict.Count > 0) { result.Add(newSubset, newDict); } } } introSW.Stop(); Program.TableCount += result.Values.Sum((t) => t.Count); return(result); }