Search code examples
c++constraintsor-toolscp-sat

Optimizing ortools cp-sat for best speed


I have a very simple program in C++ with Or-tools cp-sat solver that is taking quite long to solve. on average I am getting anywhere between 500-950 randomization per second.

Here is the code

#include <absl/log/initialize.h>
#include <stdlib.h>

#include "ortools/base/logging.h"
#include "ortools/sat/cp_model.h"
#include "ortools/sat/cp_model.pb.h"
#include "ortools/sat/cp_model_solver.h"
#include "ortools/util/sorted_interval_list.h"

void SimpleSatProgram() {
  const operations_research::Domain domain(0, 100);
  operations_research::sat::CpSolverResponse response;

  operations_research::sat::CpModelBuilder cp_model;
  operations_research::sat::IntVar a = cp_model.NewIntVar(domain);
  operations_research::sat::IntVar b = cp_model.NewIntVar(domain);
  operations_research::sat::IntVar c = cp_model.NewIntVar(domain);
  cp_model.AddEquality(a + b + c, 200);

  for (int x=0; x < 10000; x++) {
    response = operations_research::sat::Solve(cp_model.Build());

    if (response.status() == operations_research::sat::CpSolverStatus::OPTIMAL ||
        response.status() == operations_research::sat::CpSolverStatus::FEASIBLE) {
      // for (auto i : all)
      //   std::cout << std::setfill('0') << std::setw(2)
      //             << SolutionIntegerValue(response, i) << " ";
      // std::cout << "\n";
    } else {
      LOG(INFO) << "No solution found.";
    }
  }
}

int main() {
  // absl::InitializeLog();
  SimpleSatProgram();
  return EXIT_SUCCESS;
}

I have a proprietary tool that is giving close well above 120k randomizations per second in the same setup.

Is there something I can do to optimize or follow any best practices in coding to get the best performance?


Solution

  • You can try to add

    SatParameters params;
    params.set_num_workers(1);
    params.set_cp_model_presolve(false);
    

    And replace Solve() by Solvewithparameters().

    Note that cp-sat is tuned to solve meaningful non trivial models.