2010-05-29 4 views
16

У меня есть программа, которая генерирует графики с использованием разных многоуровневых моделей. Каждая многоуровневая модель состоит из поколения меньшего семенного графа (например, 50 узлов), который может быть создан из нескольких моделей (например, для каждого возможного края, выберите его включение с вероятностью p).Обработка комплексных параметров с помощью программы Boost program_options

После генерации графа семян график расширяется до более крупного (например, 1000 узлов), используя один из других наборов моделей.

В каждом из двух этапов каждой модели требуется другое количество параметров.

Я хотел бы иметь программу_опции, анализируя различные возможные параметры, в соответствии с названиями моделей.

Например, у меня есть две модели семенных графов: SA, которая имеет 1 параметр и SB, у которой есть два. Также для части расширения у меня есть две модели: 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 

и проанализировать параметры. Возможно ли это?

ответ

23

Используя custom validator и 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 функция, вероятно, нуждается в большей строгости, но вы получите идею.

Это компилируется и работает для меня.

 Смежные вопросы

  • Нет связанных вопросов^_^