-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Description
What version of OR-Tools and what language are you using?
Version: v9.15
Language: C++
Which solver are you using (e.g. CP-SAT, Routing Solver, GLOP, BOP, Gurobi)
CP-SAT
What operating system (Linux, Windows, ...) and version?
Linux
What did you do?
- Create an
operations_research::sat::Modelinstance - Register a feasible solution observer
- Register an external boolean as limit
- Run
operations_research::sat::SolveCpModelusing theModelfrom step 1
Here's a minimum example:
#include <atomic>
#include <fstream>
#include <iostream>
#include "ortools/sat/cp_model.pb.h"
#include "ortools/sat/cp_model_solver.h"
#include "ortools/util/time_limit.h"
namespace sat = operations_research::sat;
int main(int argc, char** argv) {
if (argc != 2) {
std::cerr << argv[0] << " input-proto-message\n";
return -1;
}
sat::CpModelProto cp_model;
std::ifstream in(argv[1], std::ios::binary);
if (!cp_model.ParseFromIstream(&in)) {
std::cerr << "Failed to open or parse " << argv[1] << "\n";
return -1;
}
sat::SatParameters params;
params.set_num_workers(16);
params.set_log_search_progress(true);
std::atomic<bool> stop;
sat::Model model;
model.Add(NewSatParameters(params));
model.Add(sat::NewFeasibleSolutionObserver(
[](const sat::CpSolverResponse& response) {
std::cerr << response.best_objective_bound() << " ≤ "
<< response.objective_value() << "\n";
}));
model.GetOrCreate<operations_research::TimeLimit>()
->RegisterExternalBooleanAsLimit(&stop);
sat::CpSolverResponse response = sat::SolveCpModel(cp_model, &model);
std::cout << "Solver finished, status=" << response.status() << "\n";
}I ran the above code on this input: model.zip.
It takes about 2 minutes to find an optimal solution.
What did you expect to see
After the solver finds an optimal solution, it terminates.
What did you see instead?
The solver keeps on running.
I first noticed this issue when I "manually" (using the stop variable) stopped the solver after 10 minutes and it reported an optimal solution with a tight lower bound.
I subsequently verified by adding a debug print to operations_research::SharedTimeLimit::Stop.
Anything else we should know about your project / environment
If I reverse the order of model.Add calls (register bool limit first, then the feasible solution observer), the solver terminates as expected.
I think the issue might be caused by NewFeasibleSolutionObserver creating an instance of SharedResponseManager, which forces creation of ModelSharedTimeLimit. When I later register the external boolean limit in TimeLimit, it doesn't correctly propagate to SharedTimeLimit.