2.6. Parameters

  1. C++ code:
    1. cp_is_fun3.cc

This section is divided in two parts. First, we show you how to use Google’s command line flag library. Second, we explain how to pass parameters to the CP solver.

2.6.1. Google’s gflags

The Google’s flags library is quite similar to other command line flags libraries with the noticeable difference that the flag definitions may be scattered in different files.

To define a flag, we use the corresponding macro. Google’s flags library supports six types:

  • DEFINE_bool: Boolean
  • DEFINE_int32: 32-bit integer
  • DEFINE_int64: 64-bit integer
  • DEFINE_uint64: unsigned 64-bit integer
  • DEFINE_double: double
  • DEFINE_string: C++ string

Each of them takes the same three arguments: the name of the flag, its default value, and a help string.

In file tutorials/cplusplus/chap2/cp_is_fun3.cc, we parse the base value on the command line. We first include the corresponding header and define the flag base in the global namespace:

...
#include "base/commandlineflags.h"
...
DEFINE_int64(base, 10, "Base used to solve the problem.");
...
namespace operations_research {
...

and then parse the command line:

int main(int argc, char **argv) {
  google::ParseCommandLineFlags(&argc, &argv, true);
  operations_research::CPIsFun();
  return 0;
}

Note that argc and argv are passed as pointers so that ParseCommandLineFlags() is able to modify them.

All defined flags are accessible as normal variables with the prefix FLAGS_ prepended:

const int64 kBase = FLAGS_base;

To change the base with a command line argument:

./cp_is_fun3 --base=12

If you want to know what the purpose of a flag is, just type one of the special flags on the command line:

  • --help: prints all the flags
  • --helpshort: prints all the flags defined in the same file as main()
  • --helpon=FILE: prints all the flags defined in file FILE
  • --helpmatch=S: prints all the flags defined in the files *S*.*

For other features and to learn more about this library, we refer you to the gflags documentation.

2.6.2. CP Solver‘s parameters

  1. C++ code:
    1. cp_is_fun4.cc

Parameters can be transferred to the solver in several ways.

2.6.2.1. The SolverParameters struct

First, you can invoke the constructor of the Solver that takes a SolverParameters struct:

// Use some profiling and change the default parameters of the solver
SolverParameters solver_params = SolverParameters();
// Change the profile level
solver_params.profile_level = SolverParameters::NORMAL_PROFILING;

// Constraint programming engine
Solver solver("CP is fun!", solver_params);

We can now ask for a detailed report after the search is done:

// Save profile in file
solver.ExportProfilingOverview("profile.txt");

We will see how to profile more in details in the section Profiling.

The SolverParameters struct mainly deals with the internal usage of memory and is for advanced users.

2.6.2.2. SearchMonitors

Second, you can use SearchMonitors. We have already seen how to use them to collect solutions in SolutionCollectors and Assignments to collect solutions.

Suppose we want to limit the available time to solve a problem. To pass this parameter on the command line, we define a time_limit variable:

DEFINE_int64(time_limit, 10000, "Time limit in milliseconds");

Since SearchLimit inherits from SearchMonitor, Solve() accepts it:

SolutionCollector* const all_solutions =
                                      solver.MakeAllSolutionCollector();
...
// Add time limit
SearchLimit* const time_limit = solver.MakeTimeLimit(FLAGS_time_limit);
solver.Solve(db, all_solutions, time_limit);

The search time is now limited to time_limit milliseconds.

2.6.2.3. The DefaultPhaseParameters struct

A third way is to pass parameters through the DefaultPhaseParameters struct and call MakeDefaultPhase() but we delay the discussion of this topic until the section Default search.