26 #include "absl/base/attributes.h"
27 #include "absl/memory/memory.h"
43 void Reset()
override;
51 const MPVariable*
const variable,
double new_value,
52 double old_value)
override;
61 int64_t
nodes()
const override;
67 bool IsLP()
const override;
68 bool IsMIP()
const override;
86 bool IsKnapsackModel()
const;
89 double GetVariableValueFromSolution(
const MPVariable*
var)
const;
92 std::unique_ptr<KnapsackSolver> knapsack_solver_;
93 std::vector<int64_t> profits_;
94 std::vector<std::vector<int64_t>> weights_;
95 std::vector<int64_t> capacities_;
106 if (!IsKnapsackModel()) {
107 LOG(ERROR) <<
"Model is not a knapsack model";
117 if (profits_.size() <= 64 && capacities_.size() == 1) {
121 std::make_unique<KnapsackSolver>(solver_type,
"linear_solver");
122 const double time_limit_seconds =
125 : std::numeric_limits<double>::infinity();
126 knapsack_solver_->set_time_limit(time_limit_seconds);
127 knapsack_solver_->Init(profits_, weights_, capacities_);
128 knapsack_solver_->Solve();
132 for (
int var_id = 0; var_id <
solver_->variables_.size(); ++var_id) {
134 const double value = GetVariableValueFromSolution(
var);
146 knapsack_solver_.reset(
nullptr);
150 NonIncrementalChange();
154 NonIncrementalChange();
158 NonIncrementalChange();
162 NonIncrementalChange();
166 NonIncrementalChange();
170 NonIncrementalChange();
175 double new_value,
double old_value) {
176 NonIncrementalChange();
180 NonIncrementalChange();
185 NonIncrementalChange();
189 NonIncrementalChange();
199 int constraint_index)
const {
205 int variable_index)
const {
217 return "knapsack_solver-0.0";
231 weights_.resize(
solver_->constraints_.size());
232 capacities_.resize(
solver_->constraints_.size(),
236 double fixed_usage = 0.0;
239 for (
const auto& entry :
ct->coefficients_) {
240 const int var_index = entry.first->index();
242 if (IsVariableFixedToValue(entry.first, 1.0)) {
243 fixed_usage += entry.second;
244 }
else if (!IsVariableFixedToValue(entry.first, 0.0)) {
250 const double capacity =
ct->ub() - fixed_usage;
253 double relative_error = 0.0;
254 double scaling_factor = 0.0;
257 &scaling_factor, &relative_error);
260 std::vector<int64_t> scaled_coefficients(
solver_->variables_.size(), 0);
261 for (
const auto& entry :
ct->coefficients_) {
262 if (!IsVariableFixed(entry.first)) {
263 scaled_coefficients[entry.first->index()] =
264 static_cast<int64_t
>(round(scaling_factor * entry.second)) / gcd;
267 weights_[
row].swap(scaled_coefficients);
269 static_cast<int64_t
>(round(scaling_factor *
capacity)) / gcd;
275 for (
const auto& entry :
solver_->objective_->coefficients_) {
279 if (!IsVariableFixed(entry.first)) {
283 double relative_error = 0.0;
284 double scaling_factor = 0.0;
287 &scaling_factor, &relative_error);
289 std::vector<int64_t> scaled_coefficients(
solver_->variables_.size(), 0);
290 for (
const auto& entry :
solver_->objective_->coefficients_) {
291 scaled_coefficients[entry.first->index()] =
292 static_cast<int64_t
>(round(scaling_factor * entry.second)) / gcd;
294 profits_.swap(scaled_coefficients);
313 bool KnapsackInterface::IsKnapsackModel()
const {
317 if (
var->lb() <= -1.0 ||
var->ub() >= 2.0 || !
var->integer()) {
322 for (
const auto& entry :
solver_->objective_->coefficients_) {
323 if (entry.second < 0) {
330 if (
ct->lb() > 0.0) {
333 for (
const auto& entry :
ct->coefficients_) {
334 if (entry.second < 0) {
343 bool KnapsackInterface::IsVariableFixedToValue(
const MPVariable*
var,
344 double value)
const {
345 const double lb_round_up = ceil(
var->lb());
346 return value == lb_round_up && floor(
var->ub()) == lb_round_up;
349 bool KnapsackInterface::IsVariableFixed(
const MPVariable*
var)
const {
350 return IsVariableFixedToValue(
var, 0.0) || IsVariableFixedToValue(
var, 1.0);
353 double KnapsackInterface::GetVariableValueFromSolution(
354 const MPVariable*
var)
const {
355 return !IsVariableFixedToValue(
var, 0.0) &&
356 (knapsack_solver_->BestSolutionContains(
var->index()) ||
357 IsVariableFixedToValue(
var, 1.0))
void SetScalingMode(int value) override
void SetDualTolerance(double value) override
KnapsackInterface(MPSolver *solver)
void AddRowConstraint(MPConstraint *const ct) override
void SetLpAlgorithm(int value) override
void ExtractObjective() override
void * underlying_solver() override
bool IsContinuous() const override
MPSolver::ResultStatus Solve(const MPSolverParameters ¶m) override
void SetPrimalTolerance(double value) override
void ClearConstraint(MPConstraint *const constraint) override
void SetObjectiveCoefficient(const MPVariable *const variable, double coefficient) override
void SetCoefficient(MPConstraint *const constraint, const MPVariable *const variable, double new_value, double old_value) override
MPSolver::BasisStatus row_status(int constraint_index) const override
~KnapsackInterface() override
void SetObjectiveOffset(double value) override
void SetVariableInteger(int index, bool integer) override
void SetParameters(const MPSolverParameters ¶m) override
void ExtractNewConstraints() override
std::string SolverVersion() const override
void SetRelativeMipGap(double value) override
void SetConstraintBounds(int index, double lb, double ub) override
void SetPresolveMode(int value) override
void SetVariableBounds(int index, double lb, double ub) override
void AddVariable(MPVariable *const var) override
void ExtractNewVariables() override
int64_t nodes() const override
bool IsLP() const override
bool IsMIP() const override
int64_t iterations() const override
void SetOptimizationDirection(bool maximize) override
MPSolver::BasisStatus column_status(int variable_index) const override
void ClearObjective() override
SolverType
Enum controlling which underlying algorithm is used.
@ KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER
Generic Solver.
@ KNAPSACK_64ITEMS_SOLVER
Optimized method for single dimension small problems.
The class for constraints of a Mathematical Programming (MP) model.
This mathematical programming (MP) solver class is the main class though which users build and solve ...
ResultStatus
The status of solving the problem.
@ FEASIBLE
feasible, or stopped by limit.
@ MODEL_INVALID
the model is trivially invalid (NaN coefficients, etc).
int64_t time_limit() const
BasisStatus
Advanced usage: possible basis status values for a variable and the slack variable of a linear constr...
friend class MPConstraint
void set_constraint_as_extracted(int ct_index, bool extracted)
MPSolver::ResultStatus result_status_
int last_constraint_index_
static constexpr int64_t kUnknownNumberOfNodes
void ResetExtractionInformation()
bool variable_is_extracted(int var_index) const
void set_variable_as_extracted(int var_index, bool extracted)
void SetCommonParameters(const MPSolverParameters ¶m)
SynchronizationStatus sync_status_
This class stores parameter settings for LP and MIP solvers.
The class for variables of a Mathematical Programming (MP) model.
absl::Span< const double > coefficients
A C++ wrapper that provides a simple and unified interface to several linear programming and mixed in...
Collection of objects used to extend the Constraint Solver library.
int64_t ComputeGcdOfRoundedDoubles(const std::vector< double > &x, double scaling_factor)
double GetBestScalingOfDoublesToInt64(const std::vector< double > &input, const std::vector< double > &lb, const std::vector< double > &ub, int64_t max_absolute_sum)
MPSolverInterface * BuildKnapsackInterface(MPSolver *const solver)