23 const impl::MibSFromAPI& m_parent;
26 bool m_is_heuristic_call =
false;
28 void call(CallbackEvent t_event) {
30 if (m_is_heuristic_call) {
31 for (
const auto &callback: m_parent.m_callbacks) {
32 execute(*callback, t_event);
35 std::cout <<
"Check if cuts were generated" << std::endl;
42 std::list<PrimalPoint> m_solutions;
46 void submit_heuristic_solution(
PrimalPoint t_solution) {
47 m_solutions.emplace_back(std::move(t_solution));
50 bool searchSolution(
double &t_objective_value,
double *t_new_solution)
override {
52 m_parent.m_is_heuristic_call =
true;
53 m_parent.call(InvalidSolution);
55 auto solution = m_solutions.end();
57 double current_best = m_parent.best_obj();
58 for (
auto it = m_solutions.begin(), end = m_solutions.end(); it != end ; ++it) {
59 if (it->objective_value() < current_best) {
61 current_best = it->objective_value();
65 if (solution == m_solutions.end()) {
70 const auto& osi_solver = *m_parent.m_parent.m_osi_solver;
71 const unsigned int n_vars = osi_solver.getNumCols();
72 for (
unsigned int i = 0; i < n_vars; ++i) {
73 t_new_solution[i] = solution->get(m_parent.m_parent.m_model.get_var_by_index(i));
75 t_objective_value = solution->objective_value();
85 std::list<TempCtr> m_cuts;
89 void add_user_cut(
TempCtr t_cut) {
90 m_cuts.emplace_back(std::move(t_cut));
93 void generateCuts(
const OsiSolverInterface &si, OsiCuts &cs,
const CglTreeInfo info)
override {
94 m_parent.m_is_heuristic_call =
false;
96 const double infinity = si.getInfinity();
97 const auto& model = m_parent.original_model();
99 for (
const auto& cut : m_cuts) {
101 const auto& row = cut.lhs();
102 const double rhs = cut.rhs();
104 CoinPackedVector lhs;
105 for (
const auto& [var, constant] : row) {
106 const unsigned int index = model.get_var_index(var);
107 lhs.insert(index, constant);
113 switch (cut.type()) {
114 case CtrType::LessOrEqual:
115 osi_cut.setLb(-infinity);
122 case CtrType::GreaterOrEqual:
124 osi_cut.setUb(infinity);
135 [[nodiscard]] CglCutGenerator *clone()
const override {
141 m_heuristic->setHeurCallFrequency(1);
142 m_heuristic->setStrategy(BlisHeurStrategyPeriodic);
145 BlisHeuristic& heuristic() {
return *m_heuristic; }
147 [[nodiscard]]
const BlisHeuristic& heuristic()
const {
return *m_heuristic; }
149 CglCutGenerator& cut_generator() {
return *m_cut_generator; }
151 [[nodiscard]]
const CglCutGenerator& cut_generator()
const {
return *m_cut_generator; }
153 [[nodiscard]]
const Model &original_model()
const override {
154 return m_parent.m_model;
157 void add_user_cut(
const TempCtr &t_cut)
override {
158 m_cut_generator->add_user_cut(t_cut);
161 void add_lazy_cut(
const TempCtr &t_cut)
override {
162 throw Exception(
"Not implemented.");
165 void submit_heuristic_solution(PrimalPoint t_solution)
override {
166 m_heuristic->submit_heuristic_solution(std::move(t_solution));
169 [[nodiscard]] PrimalPoint primal_solution()
const override {
171 auto& osi_solver = *m_parent.m_osi_solver;
172 const auto* solution = osi_solver.getColSolution();
173 const unsigned int n_vars = osi_solver.getNumCols();
176 result.set_reason(NotSpecified);
178 if (osi_solver.isProvenOptimal()) {
180 result.set_status(Optimal);
184 if (osi_solver.isProvenPrimalInfeasible()) {
185 result.set_status(Infeasible);
189 if (osi_solver.isProvenDualInfeasible()) {
190 result.set_status(Unbounded);
194 result.set_status(Fail);
199 for (
unsigned int i = 0; i < n_vars; ++i) {
200 const auto& var = m_parent.m_model.get_var_by_index(i);
201 result.set(var, solution[i]);
204 result.set_objective_value(m_parent.m_model.get_obj_expr().affine().constant() + osi_solver.getObjValue());
209 [[nodiscard]]
const Timer &time()
const override {
210 return m_parent.m_model.optimizer().time();
213 [[nodiscard]]
double best_obj()
const override {
214 return m_parent.get_best_obj();
217 [[nodiscard]]
double best_bound()
const override {
218 return m_parent.get_best_bound();
221 void terminate()
override {
222 throw Exception(
"Not available.");