Пример #1
0
    // ヒントを与えた上でgreedy探索を行う
    // graph: 元となったグラフ構造
    // parent_nodes, child_nodes: parent_nodesに含まれるnodeからchild_nodeに含まれるnodeにしか辺を張らない
    double learn_with_hint(graph_t& graph, std::vector<vertex_type> parent_nodes, std::vector<vertex_type> child_nodes)
    {
        // 子ノードの出現順序をランダムに
        std::shuffle(std::begin(child_nodes), std::end(child_nodes), engine_);

        // 最高評価値を保存しておく
        sampling_.make_cpt(graph);
        double eval_now = eval_(graph);

        // 親候補と子候補を全部回して様子見る
        for(auto const& child : child_nodes)
        {
            // 親ノードの出現順序をランダムに
            std::shuffle(std::begin(parent_nodes), std::end(parent_nodes), engine_);

            for(auto const& parent : parent_nodes)
            {
                if(auto edge = graph.add_edge(parent, child))
                {
                    // 辺が張れたならば,評価をする
                    sampling_.make_cpt(graph);
                    auto const eval_next = eval_(graph);

                    if(eval_next < eval_now)
                        // 良くなってるscore
                        eval_now = eval_next;
                    else
                        // 変わらない or 悪い -> 元に戻す
                        graph.erase_edge(edge);
                }
            }
        }

        return eval_now;
    }
Пример #2
0
    double operator()(graph_t& graph, std::vector<vertex_type> vertexes)
    {
        std::shuffle(vertexes.begin(), vertexes.end(), engine_);

        // bestな構造を保持しておく
        sampling_.make_cpt(graph);
        double eval_now = eval_(graph);

        for(auto it = vertexes.begin(); it != vertexes.end();)
        {
            auto const child_iter = it;
            std::shuffle(++it, vertexes.end(), engine_);

            for(auto parent_iter = it; parent_iter != vertexes.end(); ++parent_iter)
            {
                if(auto edge = graph.add_edge(*parent_iter, *child_iter))
                {
                    // 辺を貼れたなら調べてみる
                    sampling_.make_cpt(graph);
                    auto const eval_next = eval_(graph);

                    if(eval_next < eval_now)
                    {
                        // 良くなってる
                        eval_now = eval_next;
                    }
                    else
                    {
                        // 変わらない,もしくは悪い == 元に戻す
                        graph.erase_edge(edge);
                    }
                }
            }
        }

        return eval_now;
    }