19 std::unique_ptr<OptimizerFactory> m_optimizer_factory;
21 std::optional<bool> m_integer_columns;
23 std::optional<double> m_time_limit;
24 std::optional<unsigned int> m_iteration_limit;
25 std::optional<unsigned int> m_max_depth;
26 std::optional<unsigned int> m_frequency;
38 std::unique_ptr<OptimizerFactory> m_optimizer_factory;
39 bool m_integer_columns =
true;
40 double m_time_limit = std::numeric_limits<double>::max();
41 unsigned int m_iteration_limit = std::numeric_limits<unsigned int>::max();
42 unsigned int m_max_depth = 1000;
43 unsigned int m_frequency = 1;
44 unsigned int m_n_relevant_calls = 0;
46 void operator()(CallbackEvent t_event)
override;
50 [[nodiscard]]
bool with_integer_columns()
const {
return m_integer_columns; }
52 void set_integer_columns(
bool t_value) { m_integer_columns = t_value; }
54 void set_time_limit(
double t_time_limit) { m_time_limit = std::max(0., t_time_limit); }
56 void set_iteration_limit(
unsigned int t_iteration_limit) { m_iteration_limit = t_iteration_limit; }
58 void set_max_depth(
unsigned int t_max_depth) { m_max_depth = t_max_depth; }
60 void set_frequency(
unsigned int t_frequency) { m_frequency = t_frequency; }
73 IntegerMaster& with_iteration_limit(
unsigned int t_iteration_limit);
178 if (t_event != InvalidSolution) {
182 if (m_max_depth < this->node().level()) {
186 unsigned int n_relevant_calls = m_n_relevant_calls++;
188 if ( n_relevant_calls % m_frequency != 0) {
192 const auto& relaxation = this->relaxation();
193 const auto& dantzig_wolfe_optimizer = relaxation.optimizer().template as<Optimizers::DantzigWolfeDecomposition>();
194 const auto& original_model = this->original_model();
195 const auto& formulation = dantzig_wolfe_optimizer.formulation();
197 const unsigned int n_sub_problems = formulation.n_sub_problems();
199 std::unique_ptr<Model> integer_master(formulation.master().clone());
201 integer_master->unuse();
203 for (
const auto& var : original_model.vars()) {
204 const VarType type = original_model.get_var_type(var);
205 if (integer_master->has(var)) {
206 integer_master->set_var_type(var, type);
210 if (m_integer_columns) {
211 for (
unsigned int i = 0 ; i < n_sub_problems ; ++i) {
212 for (
const auto &[alpha, generator]: formulation.present_generators(i)) {
213 integer_master->set_var_type(alpha, Binary);
218 integer_master->use(*m_optimizer_factory);
220 integer_master->optimizer().set_param_time_limit(std::min(m_time_limit, relaxation.optimizer().get_remaining_time()));
222 integer_master->optimizer().set_param_iteration_limit(m_iteration_limit);
224 integer_master->optimize();
226 const int status = integer_master->get_status();
228 if (status != Optimal && status != Feasible) {
232 auto solution = save_primal(*integer_master);
235 for (
unsigned int i = 0 ; i < n_sub_problems ; ++i) {
236 for (
const auto &[alpha, generator]: formulation.present_generators(i)) {
237 if (solution.get(alpha) > .5) {
238 solution.merge_without_conflict(generator);
239 solution.set(alpha, 0.);
244 auto* info =
new NodeInfoT();
245 info->set_primal_solution(std::move(solution));
247 this->submit_heuristic_solution(info);