68 std::optional<bool> m_logs;
69 std::optional<double> m_time_limit;
70 std::optional<unsigned int> m_thread_limit;
71 std::optional<unsigned int> m_iteration_count_limit;
72 std::optional<double> m_best_bound_stop;
73 std::optional<double> m_best_obj_stop;
74 std::optional<double> m_relative_gap_tolerance;
75 std::optional<double> m_absolute_gap_tolerance;
76 std::optional<bool> m_presolve;
77 std::optional<bool> m_infeasible_or_unbounded_info;
79 CRTP& crtp() {
return static_cast<CRTP&
>(*this); }
80 const CRTP& crtp()
const {
return static_cast<const CRTP&
>(*this); }
82 void handle_default_parameters(
Optimizer* t_optimizer)
const;
239 CRTP&
conditional(
bool t_conditional_value,
const std::function<
void(CRTP&)>& t_if);
261 CRTP&
conditional(
bool t_conditional_value,
const std::function<
void(CRTP&)>& t_if,
const std::function<
void(CRTP&)>& t_else);
268 t_conditional_value ? t_if(crtp()) : t_else(crtp());
275 return conditional(t_conditional_value, t_if, [](CRTP&){});
281 if (m_infeasible_or_unbounded_info.has_value()) {
282 throw Exception(
"An infeasible-or-unbounded-info instruction has already been given.");
285 m_infeasible_or_unbounded_info = t_value;
293 if (m_presolve.has_value()) {
294 throw Exception(
"A get_param_presolve instruction has already been given.");
297 m_presolve = t_value;
305 if (m_absolute_gap_tolerance.has_value()) {
306 throw Exception(
"An absolute gap tolerance count limit has already been given.");
309 m_absolute_gap_tolerance = t_absolute_gap_tolerance;
317 if (m_relative_gap_tolerance.has_value()) {
318 throw Exception(
"A relative gap tolerance count limit has already been given.");
321 m_relative_gap_tolerance = t_relative_gap_tolerance;
329 if (m_best_obj_stop.has_value()) {
330 throw Exception(
"A user best obj count limit has already been given.");
333 m_best_obj_stop = t_user_best_obj;
341 if (m_best_bound_stop.has_value()) {
342 throw Exception(
"A user best bound limit has already been given.");
345 m_best_bound_stop = t_user_best_bound;
353 if (m_iteration_count_limit.has_value()) {
354 throw Exception(
"An iteration count limit has already been given.");
357 m_iteration_count_limit = t_iteration_count_limit;
365 if (m_thread_limit.has_value()) {
366 throw Exception(
"A thread limit has already been given.");
369 m_thread_limit = t_max_n_threads;
377 if (m_time_limit.has_value()) {
378 throw Exception(
"A time limit has already been given.");
381 m_time_limit = t_time_limit;
389 if (m_logs.has_value()) {
390 throw Exception(
"Logging settings have already been given.");
401 t_optimizer->set_param_logs(m_logs.value_or(
false));
402 t_optimizer->set_param_time_limit(m_time_limit.value_or(std::numeric_limits<double>::max()));
403 t_optimizer->set_param_threads(m_thread_limit.value_or(std::max<unsigned int>(std::thread::hardware_concurrency(), 1)));
404 t_optimizer->set_param_best_bound_stop(m_best_bound_stop.value_or(Inf));
405 t_optimizer->set_param_best_obj_stop(m_best_obj_stop.value_or(-Inf));
406 t_optimizer->set_tol_mip_relative_gap(m_relative_gap_tolerance.value_or(Tolerance::MIPRelativeGap));
407 t_optimizer->set_tol_mip_absolute_gap(m_absolute_gap_tolerance.value_or(Tolerance::MIPAbsoluteGap));
408 t_optimizer->set_param_iteration_limit(m_iteration_count_limit.value_or(std::numeric_limits<unsigned int>::max()));
409 t_optimizer->set_param_presolve(m_presolve.value_or(
true));
410 t_optimizer->set_param_infeasible_or_unbounded_info(m_infeasible_or_unbounded_info.value_or(
false));