예제 #1
0
        IEnumerable <BitVector> enumerateCsgRecursive(JoinGraph graph, BitVector S, BitVector X)
        {
            // N = neighbour(S) \ X
            BitVector N = SetOp.Substract(graph.NeighboursExcluding(S), X);

            // Console.WriteLine("N: " + BitHelper.ToString(N));

            // for all non-empty S' subsetof(N), emit (S union S')
            if (N != SetOp.EmptySet)
            {
                VancePartition partitioner = new VancePartition(N);
                foreach (var S_prime in partitioner.Next(true))
                {
                    yield return(SetOp.Union(S, S_prime));
                }

                // for all non-empty S' subsetof(N), recursively invoke (graph, (S union S'), (X union N))
                partitioner = new VancePartition(N);
                foreach (var S_prime in partitioner.Next(true))
                {
                    foreach (var v in enumerateCsgRecursive(graph,
                                                            SetOp.Union(S, S_prime), SetOp.Union(X, N)))
                    {
                        yield return(v);
                    }
                }
            }
        }
예제 #2
0
        // Naive partitioning
        //   Similar to DPBushy algorithm
        IEnumerable <CsgCmpPair> NaiveNext(JoinGraph graph, BitVector S)
        {
            // it is connected because the 1st iteration is connected and when
            // we generate for next iteration, we checked S1,S2.
            //
            Debug.Assert(graph.IsConnected(S));

            VancePartition partitioner = new VancePartition(S);

            foreach (var S1 in partitioner.Next())
            {
                c1_++;
                BitVector S2 = SetOp.Substract(S, S1);
                if (S1 < S2)
                {
                    if (!graph.IsConnected(S1) || !graph.IsConnected(S2))
                    {
                        continue;
                    }

                    yield return(new CsgCmpPair(graph, S1, S2));
                }
            }
        }
예제 #3
0
        override internal PhysicNode Run(JoinGraph graph, BigInteger expectC1)
        {
            int ntables = graph.vertices_.Count;

            Console.WriteLine("DP_Bushy #tables: " + ntables);

            // initialization: enqueue all single tables
            InitByInsertBasicTables(graph);

            // loop through all candidates trees, CP included
            ulong c1 = 0, c2 = 0;

            for (BitVector S = 1; S < (1 << ntables); S++)
            {
                if (bestTree_[S] != null)
                {
                    continue;
                }

                // need connected subgraphs if not consider CP
                if (!graph.IsConnected(S))
                {
                    // this partition enumeration is only to record #c2
                    c2 += (ulong)(new VancePartition(S)).Next().ToArray().Length;
                    continue;
                }

                // for all S_1 subset of S do
                VancePartition partitioner = new VancePartition(S);
                foreach (var S1 in partitioner.Next())
                {
                    c2++;
                    BitVector S2 = SetOp.Substract(S, S1);

                    // requires S1 < S2 to avoid commutative duplication
                    Debug.Assert(S1 != S2);
                    if (S1 < S2)
                    {
                        // need connected subgraphs if not consider CP
                        if (!graph.IsConnected(S1) || !graph.IsConnected(S2))
                        {
                            continue;
                        }

                        // find a connected pair, get the best join tree between them
                        c1++;
                        var currTree = CreateMinimalJoinTree(bestTree_[S1], bestTree_[S2]);
                        Debug.Assert(bestTree_[S].Cost() == currTree.Cost());
                    }
                }
            }

            // verify # loops for enumeration completeness:
            // 1. mumber of bushy trees
            // 2. expectC2/c2: number of trees DP considered (P68) and number of trees generated
            // 3. expectC1/c1: number of trees considered
            //
            var nbushy   = Space.Count_General_Bushy_CP(ntables);
            var expectC2 = BigInteger.Pow(3, ntables) - BigInteger.Pow(2, ntables + 1) + 1;

            Console.WriteLine("bushy: {0}, dp: {1} == c2: {2}; expected c1: {3} == c1: {4}",
                              nbushy, expectC2, c2,
                              expectC1, c1);
            Debug.Assert(expectC2 == c2);
            if (!expectC1.IsZero)
            {
                Debug.Assert(c1 == expectC1);
            }

            var result = bestTree_[(1 << ntables) - 1];

            Console.WriteLine(result.Explain());
            return(result);
        }