Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        // 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);
        }
Exemplo n.º 3
0
        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);
        }