diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 0ea6d1c7..b7cffb8f 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -1,4 +1,142 @@ -add_library(idol STATIC include/idol/modeling/numericals.h include/idol/containers/Optional.h include/idol/containers/Map.h include/idol/modeling.h include/idol/modeling/parameters/Param.h include/idol/modeling/Types.h include/idol/modeling/expressions/Constant.h src/modeling/expressions/Constant.cpp include/idol/modeling/matrix/AbstractMatrixCoefficient.h include/idol/modeling/matrix/MatrixCoefficientReference.h include/idol/modeling/matrix/MatrixCoefficient.h src/modeling/matrix/MatrixCoefficient.cpp src/modeling/matrix/MatrixCoefficientReference.cpp include/idol/modeling/constraints/TempCtr.h src/modeling/constraints/TempCtr.cpp include/idol/containers/IteratorForward.h include/idol/modeling/solutions/AbstractSolution.h include/idol/modeling/solutions/Solution.h include/idol/modeling/variables/TempVar.h include/idol/containers/Set.h include/idol/errors/NotImplemented.h include/idol/modeling/expressions/LinExpr.h include/idol/modeling/matrix/Row.h src/modeling/matrix/Row.cpp src/modeling/matrix/Column.cpp include/idol/modeling/matrix/Column.h include/idol/modeling/matrix/Matrix.h src/modeling/matrix/Matrix.cpp src/problems/generalized-assignment-problem/GAP_Instance.cpp include/idol/problems/knapsack-problem/KP_Instance.h src/problems/knapsack-problem/KP_Instance.cpp include/idol/problems/multiple-knapsack-problem/MKP_Instance.h src/problems/multiple-knapsack-problem/MKP_Instance.cpp include/idol/modeling/expressions/Expr.h include/idol/modeling/expressions/operations/operators_Var.h src/modeling/expressions/operations/operators_Var.cpp src/modeling/expressions/operations/operators_Ctr.cpp src/modeling/expressions/operations/operators_Constant.cpp include/idol/modeling/expressions/operations/operators_Constant.h include/idol/modeling/expressions/operations/operators_Ctr.h include/idol/modeling/expressions/operations/operators.h include/idol/problems/multiple-knapsack-problem/MKP_Instance.h src/problems/multiple-knapsack-problem/MKP_Instance.cpp src/problems/facility-location-problem/FLP_Instance.cpp include/idol/problems/facility-location-problem/FLP_Instance.h include/idol/problems/helpers/distances.h include/idol/problems/helpers/parse_delimited.h include/idol/modeling/expressions/operations/operators_utils.h include/idol/modeling/expressions/QuadExpr.h include/idol/modeling/expressions/AbstractExpr.h include/idol/modeling/models/Model.h include/idol/modeling/objects/Env.h include/idol/modeling/variables/Var.h src/modeling/objects/Env.cpp include/idol/modeling/variables/VarVersion.h include/idol/modeling/objects/Versions.h include/idol/modeling/objects/Object.h include/idol/modeling/objects/ObjectId.h src/modeling/models/Model.cpp include/idol/modeling/constraints/Ctr.h include/idol/modeling/constraints/CtrVersion.h include/idol/modeling/objects/Version.h src/modeling/variables/Var.cpp src/modeling/constraints/Ctr.cpp include/idol/optimizers/Optimizer.h include/idol/optimizers/wrappers/Gurobi/Optimizers_Gurobi.h include/idol/optimizers/wrappers/OptimizerWithLazyUpdates.h src/optimizers/wrappers/gurobi/Optimizers_Gurobi.cpp src/optimizers/Optimizer.cpp src/optimizers/Logger.cpp include/idol/optimizers/Algorithm.h src/optimizers/Algorithm.cpp src/optimizers/Timer.cpp include/idol/modeling/annotations/Annotation.h src/modeling/annotations/impl_Annotation.cpp include/idol/modeling/annotations/impl_Annotation.h include/idol/modeling/models/Model.h include/idol/containers/GeneratorPool.h include/idol/modeling/solutions/types.h include/idol/optimizers/wrappers/GLPK/Optimizers_GLPK.h include/idol/solvers.h src/optimizers/wrappers/GLPK/Optimizers_GLPK.cpp include/idol/optimizers/wrappers/Mosek/Optimizers_Mosek.h src/optimizers/wrappers/Mosek/Optimizers_Mosek.cpp include/idol/linear-algebra/MatrixIndices.h include/idol/linear-algebra/SquareMatrix.h include/idol/linear-algebra/to_rotated_quadratic_cone.h include/idol/optimizers/branch-and-bound/Optimizers_BranchAndBound.h include/idol/optimizers/OptimizerFactory.h include/idol/optimizers/branch-and-bound/BranchAndBound.h include/idol/optimizers/branch-and-bound/branching-rules/factories/BranchingRuleFactory.h include/idol/optimizers/branch-and-bound/node-selection-rules/factories/NodeSelectionRuleFactory.h include/idol/optimizers/branch-and-bound/node-selection-rules/factories/DepthFirst.h include/idol/optimizers/branch-and-bound/branching-rules/impls/BranchingRule.h include/idol/optimizers/branch-and-bound/node-selection-rules/impls/NodeSelectionRule.h include/idol/optimizers/branch-and-bound/nodes/Node.h include/idol/optimizers/branch-and-bound/nodes/NodeUpdator.h include/idol/optimizers/branch-and-bound/node-selection-rules/impls/DepthFirst.h include/idol/optimizers/branch-and-bound/branching-rules/impls/VariableBranchingRule.h include/idol/optimizers/branch-and-bound/node-selection-rules/factories/BreadthFirst.h include/idol/optimizers/branch-and-bound/node-selection-rules/factories/WorstBound.h include/idol/optimizers/branch-and-bound/node-selection-rules/factories/BestBound.h include/idol/optimizers/branch-and-bound/node-selection-rules/impls/WorstBound.h include/idol/optimizers/branch-and-bound/node-selection-rules/impls/BestBound.h include/idol/optimizers/branch-and-bound/node-selection-rules/impls/BreadthFirst.h include/idol/optimizers/wrappers/Gurobi/Gurobi.h include/idol/optimizers/wrappers/GLPK/GLPK.h include/idol/optimizers/wrappers/Mosek/Mosek.h include/idol/optimizers/column-generation/ColumnGeneration.h include/idol/optimizers/column-generation/Optimizers_ColumnGeneration.h src/optimizers/column-generation/ColumnGeneration.cpp src/optimizers/column-generation/Optimizers_ColumnGeneration.cpp include/idol/optimizers/dantzig-wolfe/DantzigWolfeDecomposition.h src/optimizers/dantzig-wolfe/DantzigWolfeDecomposition.cpp include/idol/optimizers/dantzig-wolfe/Optimizers_DantzigWolfeDecomposition.h src/optimizers/dantzig-wolfe/Optimizers_DantzigWolfeDecomposition.cpp src/optimizers/wrappers/gurobi/Gurobi.cpp src/optimizers/wrappers/GLPK/GLPK.cpp src/optimizers/wrappers/Mosek/Mosek.cpp include/idol/optimizers/column-generation/OptimizerFactoryWithColumnGenerationParameters.h include/idol/optimizers/branch-and-bound/callbacks/BranchAndBoundCallbackFactory.h include/idol/optimizers/column-generation/IntegerMaster.h src/optimizers/column-generation/IntegerMaster.cpp src/optimizers/wrappers/gurobi/GurobiCallbackI.cpp include/idol/optimizers/callbacks/Callback.h src/optimizers/callbacks/Callback.cpp include/idol/optimizers/callbacks/CutSeparation.h src/optimizers/callbacks/CutSeparation.cpp include/idol/optimizers/callbacks/LazyCutCallback.h include/idol/optimizers/callbacks/UserCutCallback.h include/idol/optimizers/callbacks/CallbackFactory.h include/idol/optimizers/branch-and-bound/callbacks/BranchAndBoundCallback.h include/idol/optimizers/branch-and-bound/callbacks/AbstractBranchAndBoundCallbackI.h include/idol/optimizers/branch-and-bound/callbacks/CallbackAsBranchAndBoundCallback.h include/idol/optimizers/branch-and-bound/cutting-planes/CuttingPlaneGenerator.h include/idol/optimizers/branch-and-bound/cutting-planes/CoverCuts.h include/idol/problems/staff-rostering-problem/SRP_Instance.h src/problems/staff-rostering-problem/SRP_Instance.cpp +add_library(idol STATIC + include/idol/modeling/numericals.h + include/idol/containers/Optional.h + include/idol/containers/Map.h + include/idol/modeling.h + include/idol/modeling/parameters/Param.h + include/idol/modeling/Types.h + include/idol/modeling/expressions/Constant.h + src/modeling/expressions/Constant.cpp + include/idol/modeling/matrix/AbstractMatrixCoefficient.h + include/idol/modeling/matrix/MatrixCoefficientReference.h + include/idol/modeling/matrix/MatrixCoefficient.h + src/modeling/matrix/MatrixCoefficient.cpp + src/modeling/matrix/MatrixCoefficientReference.cpp + include/idol/modeling/constraints/TempCtr.h + src/modeling/constraints/TempCtr.cpp + include/idol/containers/IteratorForward.h + include/idol/modeling/solutions/AbstractSolution.h + include/idol/modeling/solutions/Solution.h + include/idol/modeling/variables/TempVar.h + include/idol/containers/Set.h + include/idol/errors/NotImplemented.h + include/idol/modeling/expressions/LinExpr.h + include/idol/modeling/matrix/Row.h + src/modeling/matrix/Row.cpp + src/modeling/matrix/Column.cpp + include/idol/modeling/matrix/Column.h + include/idol/modeling/matrix/Matrix.h + src/modeling/matrix/Matrix.cpp + src/problems/generalized-assignment-problem/GAP_Instance.cpp + include/idol/problems/knapsack-problem/KP_Instance.h + src/problems/knapsack-problem/KP_Instance.cpp + include/idol/problems/multiple-knapsack-problem/MKP_Instance.h + src/problems/multiple-knapsack-problem/MKP_Instance.cpp + include/idol/modeling/expressions/Expr.h + include/idol/modeling/expressions/operations/operators_Var.h + src/modeling/expressions/operations/operators_Var.cpp + src/modeling/expressions/operations/operators_Ctr.cpp + src/modeling/expressions/operations/operators_Constant.cpp + include/idol/modeling/expressions/operations/operators_Constant.h + include/idol/modeling/expressions/operations/operators_Ctr.h + include/idol/modeling/expressions/operations/operators.h + include/idol/problems/multiple-knapsack-problem/MKP_Instance.h + src/problems/multiple-knapsack-problem/MKP_Instance.cpp + src/problems/facility-location-problem/FLP_Instance.cpp + include/idol/problems/facility-location-problem/FLP_Instance.h + include/idol/problems/helpers/distances.h + include/idol/problems/helpers/parse_delimited.h + include/idol/modeling/expressions/operations/operators_utils.h + include/idol/modeling/expressions/QuadExpr.h + include/idol/modeling/expressions/AbstractExpr.h + include/idol/modeling/models/Model.h + include/idol/modeling/objects/Env.h + include/idol/modeling/variables/Var.h + src/modeling/objects/Env.cpp + include/idol/modeling/variables/VarVersion.h + include/idol/modeling/objects/Versions.h + include/idol/modeling/objects/Object.h + include/idol/modeling/objects/ObjectId.h + src/modeling/models/Model.cpp + include/idol/modeling/constraints/Ctr.h + include/idol/modeling/constraints/CtrVersion.h + include/idol/modeling/objects/Version.h + src/modeling/variables/Var.cpp + src/modeling/constraints/Ctr.cpp + include/idol/optimizers/Optimizer.h + include/idol/optimizers/wrappers/Gurobi/Optimizers_Gurobi.h + include/idol/optimizers/wrappers/OptimizerWithLazyUpdates.h + src/optimizers/wrappers/gurobi/Optimizers_Gurobi.cpp + src/optimizers/Optimizer.cpp + src/optimizers/Logger.cpp + include/idol/optimizers/Algorithm.h + src/optimizers/Algorithm.cpp + src/optimizers/Timer.cpp + include/idol/modeling/annotations/Annotation.h + src/modeling/annotations/impl_Annotation.cpp + include/idol/modeling/annotations/impl_Annotation.h + include/idol/modeling/models/Model.h + include/idol/containers/GeneratorPool.h + include/idol/modeling/solutions/types.h + include/idol/optimizers/wrappers/GLPK/Optimizers_GLPK.h + include/idol/solvers.h + src/optimizers/wrappers/GLPK/Optimizers_GLPK.cpp + include/idol/optimizers/wrappers/Mosek/Optimizers_Mosek.h + src/optimizers/wrappers/Mosek/Optimizers_Mosek.cpp + include/idol/linear-algebra/MatrixIndices.h + include/idol/linear-algebra/SquareMatrix.h + include/idol/linear-algebra/to_rotated_quadratic_cone.h + include/idol/optimizers/branch-and-bound/Optimizers_BranchAndBound.h + include/idol/optimizers/OptimizerFactory.h + include/idol/optimizers/branch-and-bound/BranchAndBound.h + include/idol/optimizers/branch-and-bound/branching-rules/factories/BranchingRuleFactory.h + include/idol/optimizers/branch-and-bound/node-selection-rules/factories/NodeSelectionRuleFactory.h + include/idol/optimizers/branch-and-bound/node-selection-rules/factories/DepthFirst.h + include/idol/optimizers/branch-and-bound/branching-rules/impls/BranchingRule.h + include/idol/optimizers/branch-and-bound/node-selection-rules/impls/NodeSelectionRule.h + include/idol/optimizers/branch-and-bound/nodes/Node.h + include/idol/optimizers/branch-and-bound/nodes/NodeUpdator.h + include/idol/optimizers/branch-and-bound/node-selection-rules/impls/DepthFirst.h + include/idol/optimizers/branch-and-bound/branching-rules/impls/VariableBranchingRule.h + include/idol/optimizers/branch-and-bound/node-selection-rules/factories/BreadthFirst.h + include/idol/optimizers/branch-and-bound/node-selection-rules/factories/WorstBound.h + include/idol/optimizers/branch-and-bound/node-selection-rules/factories/BestBound.h + include/idol/optimizers/branch-and-bound/node-selection-rules/impls/WorstBound.h + include/idol/optimizers/branch-and-bound/node-selection-rules/impls/BestBound.h + include/idol/optimizers/branch-and-bound/node-selection-rules/impls/BreadthFirst.h + include/idol/optimizers/wrappers/Gurobi/Gurobi.h + include/idol/optimizers/wrappers/GLPK/GLPK.h + include/idol/optimizers/wrappers/Mosek/Mosek.h + include/idol/optimizers/column-generation/ColumnGeneration.h + include/idol/optimizers/column-generation/Optimizers_ColumnGeneration.h + src/optimizers/column-generation/ColumnGeneration.cpp + src/optimizers/column-generation/Optimizers_ColumnGeneration.cpp + include/idol/optimizers/dantzig-wolfe/DantzigWolfeDecomposition.h + src/optimizers/dantzig-wolfe/DantzigWolfeDecomposition.cpp + include/idol/optimizers/dantzig-wolfe/Optimizers_DantzigWolfeDecomposition.h + src/optimizers/dantzig-wolfe/Optimizers_DantzigWolfeDecomposition.cpp + src/optimizers/wrappers/gurobi/Gurobi.cpp + src/optimizers/wrappers/GLPK/GLPK.cpp + src/optimizers/wrappers/Mosek/Mosek.cpp + include/idol/optimizers/column-generation/OptimizerFactoryWithColumnGenerationParameters.h + include/idol/optimizers/branch-and-bound/callbacks/BranchAndBoundCallbackFactory.h + include/idol/optimizers/column-generation/IntegerMaster.h + src/optimizers/column-generation/IntegerMaster.cpp + src/optimizers/wrappers/gurobi/GurobiCallbackI.cpp + include/idol/optimizers/callbacks/Callback.h + src/optimizers/callbacks/Callback.cpp + include/idol/optimizers/callbacks/CutSeparation.h + src/optimizers/callbacks/CutSeparation.cpp + include/idol/optimizers/callbacks/LazyCutCallback.h + include/idol/optimizers/callbacks/UserCutCallback.h + include/idol/optimizers/callbacks/CallbackFactory.h + include/idol/optimizers/branch-and-bound/callbacks/BranchAndBoundCallback.h + include/idol/optimizers/branch-and-bound/callbacks/AbstractBranchAndBoundCallbackI.h + include/idol/optimizers/branch-and-bound/callbacks/CallbackAsBranchAndBoundCallback.h + include/idol/optimizers/branch-and-bound/cutting-planes/CuttingPlaneGenerator.h + include/idol/optimizers/branch-and-bound/cutting-planes/CoverCuts.h + include/idol/problems/staff-rostering-problem/SRP_Instance.h + src/problems/staff-rostering-problem/SRP_Instance.cpp src/modeling/numericals.cpp include/idol/optimizers/callbacks/SimpleRounding.h src/optimizers/callbacks/SimpleRounding.cpp @@ -93,6 +231,12 @@ endif() set(AVAILABLE_MILP_SOLVERS "${AVAILABLE_MILP_SOLVERS}" PARENT_SCOPE) +if (${WITH_PROFILING}) + target_compile_options(idol PRIVATE -pg) + set(CMAKE_C_COMPILER gcc) + set(CMAKE_CPP_COMPILER g++) +endif() + target_include_directories( idol PUBLIC @@ -135,5 +279,6 @@ install(FILES "${idol_SOURCE_DIR}/cmake/FindGLPK.cmake" "${idol_SOURCE_DIR}/cmake/FindMOSEK.cmake" "${idol_SOURCE_DIR}/cmake/FindEIGEN.cmake" + "${idol_SOURCE_DIR}/cmake/FindROBINHOOD.cmake" DESTINATION lib/cmake/idol ) diff --git a/lib/include/idol/optimizers/branch-and-bound/Optimizers_BranchAndBound.h b/lib/include/idol/optimizers/branch-and-bound/Optimizers_BranchAndBound.h index 93343ffd..3c434ec1 100644 --- a/lib/include/idol/optimizers/branch-and-bound/Optimizers_BranchAndBound.h +++ b/lib/include/idol/optimizers/branch-and-bound/Optimizers_BranchAndBound.h @@ -381,20 +381,26 @@ void idol::Optimizers::BranchAndBound::hook_optimize() { m_node_updator->clear_local_updates(); + if (get_status() == Fail) { + return; + } + if (!m_incumbent.has_value()) { if (is_pos_inf(get_best_obj())) { set_status(Infeasible); return; - } else if (is_neg_inf(get_best_obj())) { + } + + if (is_neg_inf(get_best_obj())) { set_status(Unbounded); return; } - } else { - set_status(Feasible); } + set_status(Feasible); + if (gap_is_closed()) { set_status(Optimal); set_reason(Proved); diff --git a/lib/include/idol/optimizers/wrappers/HiGHS/Optimizers_HiGHS.h b/lib/include/idol/optimizers/wrappers/HiGHS/Optimizers_HiGHS.h index cf39b629..1db4dfc9 100644 --- a/lib/include/idol/optimizers/wrappers/HiGHS/Optimizers_HiGHS.h +++ b/lib/include/idol/optimizers/wrappers/HiGHS/Optimizers_HiGHS.h @@ -91,6 +91,8 @@ class idol::Optimizers::HiGHS : public OptimizerWithLazyUpdates { void set_param_presolve(bool t_value) override; + void set_param_log_level(LogLevel t_log_level) override; + }; #endif diff --git a/lib/src/modeling/expressions/Constant.cpp b/lib/src/modeling/expressions/Constant.cpp index b4b09021..f07a318e 100644 --- a/lib/src/modeling/expressions/Constant.cpp +++ b/lib/src/modeling/expressions/Constant.cpp @@ -14,8 +14,10 @@ idol::Constant::Constant(const Param &t_param, double t_value) : m_linear_terms( } } -idol::Constant::Constant(const idol::Param &t_param_1, const idol::Param &t_param_2, double t_value) - : m_quadratic_terms({{{t_param_1, t_param_2}, t_value}}) { +idol::Constant::Constant(const idol::Param &t_param_1, const idol::Param &t_param_2, double t_value) { + + m_quadratic_terms.emplace(std::make_pair<>(t_param_1, t_param_2), t_value); + if (equals(t_value, 0., Tolerance::Sparsity)) { m_quadratic_terms.clear(); } diff --git a/lib/src/optimizers/column-generation/Optimizers_ColumnGeneration.cpp b/lib/src/optimizers/column-generation/Optimizers_ColumnGeneration.cpp index da967c45..73453a4a 100644 --- a/lib/src/optimizers/column-generation/Optimizers_ColumnGeneration.cpp +++ b/lib/src/optimizers/column-generation/Optimizers_ColumnGeneration.cpp @@ -655,25 +655,34 @@ void idol::Optimizers::ColumnGeneration::Subproblem::update_objective(bool t_far for (const auto &[ctr, constant] : m_generation_pattern.linear()) { objective += constant.numerical() * -t_duals.get(ctr); for (const auto &[param, coeff] : constant.linear()) { - objective += -t_duals.get(ctr) * coeff * param.as(); + const double cost = -t_duals.get(ctr) * coeff; + if (!equals(cost, 0., Tolerance::Sparsity)) { + objective += cost * param.as(); + } } for (const auto &[pair, coeff] : constant.quadratic()) { - objective += -t_duals.get(ctr) * coeff * pair.first.as() * pair.second.as(); + const double cost = -t_duals.get(ctr) * coeff; + if (!equals(cost, 0., Tolerance::Sparsity)) { + objective += cost * pair.first.as() * pair.second.as(); + } } } if (!t_farkas_pricing) { for (const auto &[param, coeff] : m_generation_pattern.obj().linear()) { - objective += coeff * param.as(); + if (!equals(coeff, 0., Tolerance::Sparsity)) { + objective += coeff * param.as(); + } } for (const auto &[pair, coeff] : m_generation_pattern.obj().quadratic()) { - objective += coeff * pair.first.as() * pair.second.as(); + if (!equals(coeff, 0., Tolerance::Sparsity)) { + objective += coeff * pair.first.as() * pair.second.as(); + } } } m_model->set_obj_expr(std::move(objective)); - // m_model->write(std::string("pricing_").append(std::to_string(m_index)).append(".lp")); } void idol::Optimizers::ColumnGeneration::Subproblem::optimize() { diff --git a/lib/src/optimizers/wrappers/HiGHS/Optimizers_HiGHS.cpp b/lib/src/optimizers/wrappers/HiGHS/Optimizers_HiGHS.cpp index 3bd57de7..0d7ee9d2 100644 --- a/lib/src/optimizers/wrappers/HiGHS/Optimizers_HiGHS.cpp +++ b/lib/src/optimizers/wrappers/HiGHS/Optimizers_HiGHS.cpp @@ -425,4 +425,15 @@ void idol::Optimizers::HiGHS::set_solution_index(unsigned int t_index) { } } +void idol::Optimizers::HiGHS::set_param_log_level(idol::LogLevel t_log_level) { + + if (t_log_level > Mute) { + m_model.setOptionValue("output_flag", true); + } else { + m_model.setOptionValue("output_flag", false); + } + + Optimizer::set_param_log_level(t_log_level); +} + #endif