16

さまざまなマルチレベル モデルを使用してグラフを生成するプログラムがあります。各マルチレベル モデルは、いくつかのモデルから作成できる小さなシード グラフ (たとえば、50 ノード) の生成で構成されます (たとえば、可能なエッジごとに、確率 p で含めることを選択します)。

シード グラフの生成後、グラフは別のモデル セットの 1 つを使用して、より大きなグラフ (たとえば 1000 ノード) に拡張されます。

2 つの段階のそれぞれで、各モデルには異なる数のパラメーターが必要です。

モデルの名前に応じて、program_options にさまざまな可能なパラメーターを解析させたいと思います。

たとえば、2 つのシード グラフ モデルがあるとします。パラメータが 1 つある SA と、パラメータが 2 つある SB です。拡張部分についても、2 つのモデルがあります。A と B で、それぞれ 1 つと 2 つのパラメーターがあります。私は次のようなことができるようにしたいと思います:

./graph_generator --seed=SA 0.1 --expansion=A 0.2
./graph_generator --seed=SB 0.1 3 --expansion=A 0.2
./graph_generator --seed=SA 0.1 --expansion=B 10 20
./graph_generator --seed=SB 0.1 3 --expansion=B 10 20

パラメータを正しく解析します。それは可能ですか?

4

1 に答える 1

23

カスタム バリデーターboost::program_options::value::multitokenを使用することで、目的の結果を得ることができます。

#include <iostream>
#include <boost/lexical_cast.hpp>
#include <boost/optional.hpp>
#include <boost/program_options.hpp>

// Holds parameters for seed/expansion model
struct Model
{
    std::string type;
    boost::optional<float> param1;
    boost::optional<float> param2;
};

// Called by program_options to parse a set of Model arguments
void validate(boost::any& v, const std::vector<std::string>& values,
              Model*, int)
{
    Model model;
    // Extract tokens from values string vector and populate Model struct.
    if (values.size() == 0)
    {
        throw boost::program_options::validation_error(
            "Invalid model specification");
    }
    model.type = values.at(0); // Should validate for A/B
    if (values.size() >= 2)
        model.param1 = boost::lexical_cast<float>(values.at(1));
    if (values.size() >= 3)
        model.param2 = boost::lexical_cast<float>(values.at(2));

    v = model;
}

int main(int argc, char* argv[])
{
    Model seedModel, expansionModel;

    namespace po = boost::program_options;
    po::options_description options("Generic options");
    options.add_options()
        ("seed",
             po::value<Model>(&seedModel)->multitoken(),
             "seed graph model")
        ("expansion",
             po::value<Model>(&expansionModel)->multitoken(),
             "expansion model")
        ;

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, options), vm);
    po::notify(vm);

    std::cout << "Seed type: " << seedModel.type << "\n";
    if (seedModel.param1)
        std::cout << "Seed param1: " << *(seedModel.param1) << "\n";
    if (seedModel.param2)
        std::cout << "Seed param2: " << *(seedModel.param2) << "\n";

    std::cout << "Expansion type: " << expansionModel.type << "\n";
    if (expansionModel.param1)
        std::cout << "Expansion param1: " << *(expansionModel.param1) << "\n";
    if (expansionModel.param2)
        std::cout << "Expansion param2: " << *(expansionModel.param2) << "\n";

    return 0;
}

関数にはvalidateおそらくもっと厳密さが必要ですが、アイデアは得られます。

これはコンパイルされ、私のために機能します。

于 2010-05-30T15:37:46.277 に答える