Пример #1
0
// ----------------------------------------------------------------------
void generate_recursive(TFront *pf, TObjVec *pt, size_t num_objs,
                        size_t left, size_t total, size_t element)
{
    if (element == num_objs-1)
    {
        (*pt)[element] = left;
        pf->push_back(*pt);
    }
    else
    {
        for (size_t i=0; i<=left; i+=1)
        {
            (*pt)[element] = i;
            generate_recursive(pf, pt, num_objs, left-i, total, element+1);
        }
    }
}
Пример #2
0
        Tree(InputMatrix<Categ,Scalar>& inMx,InfoType inf_measure)
            : root { new Node<Categ,Scalar>(nullptr,{})},
              information_measure {inf_measure}
            {
                std::vector<bool> is_used (inMx[0].features.size(),false);
                //is_used[j] will record if feature j was already tested for

                InternalMatrix internal_mx;
                //vector of pointers to be the internal representation
                //used in elaborating the tree

                for(int i = 0; i < inMx.size(); i++) {
                    internal_mx.push_back(&inMx[i]);
                }

                generate_recursive(internal_mx,&(*root),is_used);
                //&*root is there because we want to pass a Node*,
                //not a std::unique_ptr<Node>

            }
Пример #3
0
// ----------------------------------------------------------------------
void GenerateWeight(TFront *pf, size_t M, size_t p)
{
    TObjVec pt(M);

    generate_recursive(pf, &pt, M, p, p, 0);
}
Пример #4
0
        void generate_recursive(InternalMatrix& inMx,
                                Node<Categ,Scalar>* from,
                                std::vector<bool>& is_used)
            {
                std::vector<Test<Scalar>> tst_vect{};
                double start_info = information(inMx);

                //generate tests
                for(int i = 0; i < is_used.size(); i++) {
                    if(!is_used[i]) {
                        Test<Scalar> cnt_test (0.0, i,
                            [i](const std::vector<Scalar>& f) {
                                            return static_cast<unsigned>(f[i]); } );

                        tst_vect.push_back(cnt_test);
                    }
                }

                if(tst_vect.size() == 0) return; //catch base case

                //calculate efficiencies
                for(auto& cnt_test : tst_vect) {
                    std::unordered_map<unsigned,InternalMatrix> buckets;
                    for(auto input : inMx) {
                        buckets[cnt_test(input->features)].push_back(input);
                    }

                    double total_info = 0;
                    for(auto& matrix : buckets) {
                        total_info += information(matrix.second);
                    }

                    cnt_test.info_gain = start_info - total_info;
                }


                std::sort(tst_vect.begin(),tst_vect.end(),
                          [](Test<Scalar> a, Test<Scalar> b) {
                                return (a.info_gain > b.info_gain); });

                //mark best test
                is_used[tst_vect[0].feature_index] = true;
                from->set_test(tst_vect[0].test_fn);


                //for all buckets produced at this level,
                //generate children recursively
                std::unordered_map<unsigned,InternalMatrix> buckets;

                for(auto input : inMx) {
                        buckets[tst_vect[0](input->features)].push_back(input);
                    }

                for(auto inputMx = buckets.begin(); inputMx != buckets.end(); inputMx++) {
                        Node<Categ,Scalar>* cnt_child = new Node<Categ,Scalar>(from, //parent pointer
                                                        tst_vect[0](inputMx->second[0]->features)) ; //test value
                        from->link_child(cnt_child);
                        if(!information(inputMx->second)) {
                            //notice we have gained all information
                            //that can be gained in this subproblem,
                            //time to set them labels and return
                            cnt_child->set_label( inputMx->second[0]->category );
                            continue;
                        } else {
                            generate_recursive(inputMx->second,cnt_child,is_used);
                        }
                    }

                //we are heading back up the tree, ergo we must
                //mark current test as unused in the higher levels
                is_used[tst_vect[0].feature_index] = false;


            }