14#ifndef OR_TOOLS_ALGORITHMS_KNAPSACK_SOLVER_H_
15#define OR_TOOLS_ALGORITHMS_KNAPSACK_SOLVER_H_
22#include "absl/strings/string_view.h"
27class BaseKnapsackSolver;
169#if defined(USE_XPRESS)
178#if defined(USE_CPLEX)
216 void Init(
const std::vector<int64_t>& profits,
217 const std::vector<std::vector<int64_t> >& weights,
218 const std::vector<int64_t>& capacities);
244 time_limit_seconds_ = time_limit_seconds;
245 time_limit_ = std::make_unique<TimeLimit>(time_limit_seconds_);
251 int ReduceCapacities(
int num_items,
252 const std::vector<std::vector<int64_t> >& weights,
253 const std::vector<int64_t>& capacities,
254 std::vector<std::vector<int64_t> >* reduced_weights,
255 std::vector<int64_t>* reduced_capacities);
256 int ReduceProblem(
int num_items);
257 void ComputeAdditionalProfit(
const std::vector<int64_t>& profits);
258 void InitReducedProblem(
const std::vector<int64_t>& profits,
259 const std::vector<std::vector<int64_t> >& weights,
260 const std::vector<int64_t>& capacities);
262 std::unique_ptr<BaseKnapsackSolver> solver_;
263 std::vector<bool> known_value_;
264 std::vector<bool> best_solution_;
265 bool is_solution_optimal_ =
false;
266 std::vector<int> mapping_reduced_item_id_;
267 bool is_problem_solved_;
268 int64_t additional_profit_;
270 double time_limit_seconds_;
271 std::unique_ptr<TimeLimit> time_limit_;
325 ?
static_cast<double>(
profit) /
static_cast<double>(
weight)
356 int depth()
const {
return depth_; }
380 int64_t current_profit_;
381 int64_t profit_upper_bound_;
441 void Init(
int number_of_items);
448 bool is_bound(
int id)
const {
return is_bound_.at(
id); }
449 bool is_in(
int id)
const {
return is_in_.at(
id); }
456 std::vector<bool> is_bound_;
457 std::vector<bool> is_in_;
481 void Init(
const std::vector<int64_t>& profits,
482 const std::vector<int64_t>& weights);
523 std::vector<bool>*
solution)
const = 0;
526 const std::vector<KnapsackItemPtr>&
items()
const {
return items_; }
532 std::vector<KnapsackItemPtr> items_;
533 int64_t current_profit_;
534 int64_t profit_lower_bound_;
535 int64_t profit_upper_bound_;
583 std::vector<bool>*
solution)
const override;
594 int64_t GetAdditionalProfit(int64_t remaining_capacity,
595 int break_item_id)
const;
597 const int64_t capacity_;
598 int64_t consumed_capacity_;
600 std::vector<KnapsackItemPtr> sorted_items_;
609 : solver_name_(solver_name) {}
613 virtual void Init(
const std::vector<int64_t>& profits,
614 const std::vector<std::vector<int64_t> >& weights,
615 const std::vector<int64_t>& capacities) = 0;
626 bool* is_solution_optimal) = 0;
631 virtual std::string
GetName()
const {
return solver_name_; }
634 const std::string solver_name_;
659 void Init(
const std::vector<int64_t>& profits,
660 const std::vector<std::vector<int64_t> >& weights,
661 const std::vector<int64_t>& capacities)
override;
671 primary_propagator_id_ = primary_propagator_id;
676 bool* is_solution_optimal)
override;
679 return best_solution_.at(item_id);
695 void UpdateBestSolution();
702 int64_t GetAggregatedProfitUpperBound()
const;
703 bool HasOnePropagator()
const {
return propagators_.size() == 1; }
704 int64_t GetCurrentProfit()
const {
705 return propagators_.at(primary_propagator_id_)->current_profit();
707 int64_t GetNextItemId()
const {
708 return propagators_.at(primary_propagator_id_)->GetNextItemId();
711 std::vector<KnapsackPropagator*> propagators_;
712 int primary_propagator_id_;
713 std::vector<KnapsackSearchNode*> search_nodes_;
714 KnapsackState state_;
715 int64_t best_solution_profit_;
716 std::vector<bool> best_solution_;
virtual bool best_solution(int item_id) const =0
Returns true if the item 'item_id' is packed in the optimal knapsack.
virtual int64_t Solve(TimeLimit *time_limit, double time_limit_in_seconds, bool *is_solution_optimal)=0
Solves the problem and returns the profit of the optimal solution.
virtual void Init(const std::vector< int64_t > &profits, const std::vector< std::vector< int64_t > > &weights, const std::vector< int64_t > &capacities)=0
Initializes the solver and enters the problem to be solved.
BaseKnapsackSolver(absl::string_view solver_name)
virtual ~BaseKnapsackSolver()=default
virtual void GetLowerAndUpperBoundWhenItem(int item_id, bool is_item_in, int64_t *lower_bound, int64_t *upper_bound)
--— BaseKnapsackSolver --—
virtual std::string GetName() const
void CopyCurrentStateToSolutionPropagator(std::vector< bool > *solution) const override
~KnapsackCapacityPropagator() override
KnapsackCapacityPropagator & operator=(const KnapsackCapacityPropagator &)=delete
KnapsackCapacityPropagator(const KnapsackState &state, int64_t capacity)
--— KnapsackCapacityPropagator --—
void InitPropagator() override
KnapsackCapacityPropagator(const KnapsackCapacityPropagator &)=delete
This type is neither copyable nor movable.
bool UpdatePropagator(bool revert, const KnapsackAssignment &assignment) override
Returns false when the propagator fails.
int GetNextItemId() const override
void ComputeProfitBounds() override
void GetLowerAndUpperBoundWhenItem(int item_id, bool is_item_in, int64_t *lower_bound, int64_t *upper_bound) override
--— BaseKnapsackSolver --—
void set_primary_propagator_id(int primary_propagator_id)
KnapsackGenericSolver(const KnapsackGenericSolver &)=delete
This type is neither copyable nor movable.
bool best_solution(int item_id) const override
Returns true if the item 'item_id' is packed in the optimal knapsack.
~KnapsackGenericSolver() override
int GetNumberOfItems() const
void Init(const std::vector< int64_t > &profits, const std::vector< std::vector< int64_t > > &weights, const std::vector< int64_t > &capacities) override
Initializes the solver and enters the problem to be solved.
KnapsackGenericSolver & operator=(const KnapsackGenericSolver &)=delete
KnapsackGenericSolver(const std::string &solver_name)
--— KnapsackGenericSolver --—
int64_t Solve(TimeLimit *time_limit, double time_limit_in_seconds, bool *is_solution_optimal) override
Solves the problem and returns the profit of the optimal solution.
KnapsackPropagator & operator=(const KnapsackPropagator &)=delete
void set_profit_upper_bound(int64_t profit)
virtual int GetNextItemId() const =0
void CopyCurrentStateToSolution(bool has_one_propagator, std::vector< bool > *solution) const
int64_t profit_lower_bound() const
bool Update(bool revert, const KnapsackAssignment &assignment)
void set_profit_lower_bound(int64_t profit)
void Init(const std::vector< int64_t > &profits, const std::vector< int64_t > &weights)
Initializes data structure and then calls InitPropagator.
virtual void ComputeProfitBounds()=0
const KnapsackState & state() const
KnapsackPropagator(const KnapsackState &state)
--— KnapsackPropagator --—
virtual ~KnapsackPropagator()
virtual void CopyCurrentStateToSolutionPropagator(std::vector< bool > *solution) const =0
KnapsackPropagator(const KnapsackPropagator &)=delete
This type is neither copyable nor movable.
virtual bool UpdatePropagator(bool revert, const KnapsackAssignment &assignment)=0
int64_t profit_upper_bound() const
const std::vector< KnapsackItemPtr > & items() const
virtual void InitPropagator()=0
int64_t current_profit() const
int64_t profit_upper_bound() const
KnapsackSearchNode(const KnapsackSearchNode *parent, const KnapsackAssignment &assignment)
--— KnapsackSearchNode --—
const KnapsackAssignment & assignment() const
void set_current_profit(int64_t profit)
KnapsackSearchNode & operator=(const KnapsackSearchNode &)=delete
void set_next_item_id(int id)
int64_t current_profit() const
const KnapsackSearchNode * parent() const
KnapsackSearchNode(const KnapsackSearchNode &)=delete
This type is neither copyable nor movable.
void set_profit_upper_bound(int64_t profit)
const KnapsackSearchNode & via() const
KnapsackSearchPath(const KnapsackSearchNode &from, const KnapsackSearchNode &to)
--— KnapsackSearchPath --—
const KnapsackSearchNode & to() const
const KnapsackSearchNode & from() const
KnapsackSearchPath(const KnapsackSearchPath &)=delete
This type is neither copyable nor movable.
const KnapsackSearchNode * MoveUpToDepth(const KnapsackSearchNode &node, int depth) const
KnapsackSearchPath & operator=(const KnapsackSearchPath &)=delete
bool use_reduction() const
void set_time_limit(double time_limit_seconds)
KnapsackSolver(const KnapsackSolver &)=delete
This type is neither copyable nor movable.
bool BestSolutionContains(int item_id) const
void Init(const std::vector< int64_t > &profits, const std::vector< std::vector< int64_t > > &weights, const std::vector< int64_t > &capacities)
KnapsackSolver(const std::string &solver_name)
--— KnapsackSolver --—
@ KNAPSACK_DIVIDE_AND_CONQUER_SOLVER
@ KNAPSACK_BRUTE_FORCE_SOLVER
@ KNAPSACK_MULTIDIMENSION_XPRESS_MIP_SOLVER
@ KNAPSACK_MULTIDIMENSION_CP_SAT_SOLVER
@ KNAPSACK_DYNAMIC_PROGRAMMING_SOLVER
@ KNAPSACK_64ITEMS_SOLVER
@ KNAPSACK_MULTIDIMENSION_SCIP_MIP_SOLVER
@ KNAPSACK_MULTIDIMENSION_CPLEX_MIP_SOLVER
@ KNAPSACK_MULTIDIMENSION_CBC_MIP_SOLVER
@ KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER
bool IsSolutionOptimal() const
KnapsackSolver & operator=(const KnapsackSolver &)=delete
virtual ~KnapsackSolver()
void set_use_reduction(bool use_reduction)
std::string GetName() const
KnapsackState(const KnapsackState &)=delete
This type is neither copyable nor movable.
bool UpdateState(bool revert, const KnapsackAssignment &assignment)
Returns false when the state is invalid.
void Init(int number_of_items)
Initializes vectors with number_of_items set to false (i.e. not bound yet).
int GetNumberOfItems() const
KnapsackState & operator=(const KnapsackState &)=delete
bool is_bound(int id) const
KnapsackState()
--— KnapsackState --—
In SWIG mode, we don't want anything besides these top-level includes.
KnapsackItem * KnapsackItemPtr
KnapsackAssignment(int _item_id, bool _is_in)
KnapsackItem(int _id, int64_t _weight, int64_t _profit)
double GetEfficiency(int64_t profit_max) const