14 #ifndef OR_TOOLS_SAT_LINEAR_PROGRAMMING_CONSTRAINT_H_
15 #define OR_TOOLS_SAT_LINEAR_PROGRAMMING_CONSTRAINT_H_
25 #include "absl/container/flat_hash_map.h"
39 #include "ortools/sat/sat_parameters.pb.h"
84 IntegerValue multiplier,
85 const std::vector<std::pair<glop::ColIndex, IntegerValue>>& terms);
94 const std::vector<IntegerVariable>& integer_variables,
98 std::vector<std::pair<glop::ColIndex, IntegerValue>>
GetTerms();
102 return dense_vector_[
col];
111 bool is_sparse_ =
true;
112 std::vector<glop::ColIndex> non_zeros_;
136 class LinearProgrammingDispatcher;
146 absl::Span<const IntegerVariable> vars);
183 return static_cast<int>(integer_variables_.size());
186 return integer_variables_;
234 return total_num_simplex_iterations_;
242 if (optimal_constraints_.empty())
return nullptr;
243 return optimal_constraints_.back().get();
247 return optimal_constraints_;
253 bool BranchOnVar(IntegerVariable
var);
261 std::vector<IntegerLiteral>* integer_reason);
268 bool CreateLpFromConstraintManager();
290 bool AddCutFromConstraints(
291 const std::string&
name,
292 const std::vector<std::pair<glop::RowIndex, IntegerValue>>&
293 integer_multipliers);
296 bool PostprocessAndAddCut(
const std::string&
name,
const std::string& info,
297 IntegerVariable first_slack,
302 void AddObjectiveCut();
305 void AddZeroHalfCuts();
308 void UpdateBoundsOfLpVariables();
313 bool ExactLpReasonning();
318 bool FillExactDualRayReason();
321 int64_t CalculateDegeneracy();
329 std::vector<std::pair<glop::RowIndex, IntegerValue>> ScaleLpMultiplier(
330 bool take_objective_into_account,
331 const std::vector<std::pair<glop::RowIndex, double>>& lp_multipliers,
339 bool ComputeNewLinearConstraint(
340 const std::vector<std::pair<glop::RowIndex, IntegerValue>>&
348 void AdjustNewLinearConstraint(
349 std::vector<std::pair<glop::RowIndex, IntegerValue>>* integer_multipliers,
354 using LinearExpression = std::vector<std::pair<glop::ColIndex, IntegerValue>>;
358 void ConvertToLinearConstraint(
375 void ReducedCostStrengtheningDeductions(
double cp_objective_delta);
382 glop::ColIndex GetMirrorVariable(IntegerVariable positive_variable);
386 void UpdateAverageReducedCosts();
397 void UpdateSimplexIterationLimit(int64_t min_iter, int64_t max_iter);
402 static constexpr
double kCpEpsilon = 1e-4;
405 static constexpr
double kLpEpsilon = 1e-6;
409 static constexpr
double kZeroTolerance = 1e-12;
417 struct LinearConstraintInternal {
422 LinearExpression integer_objective_;
423 IntegerValue integer_objective_offset_ = IntegerValue(0);
424 IntegerValue objective_infinity_norm_ = IntegerValue(0);
429 glop::GlopParameters simplex_params_;
433 int64_t next_simplex_iter_ = 500;
439 ZeroHalfCutHelper zero_half_cut_helper_;
440 CoverCutHelper cover_cut_helper_;
441 FlowCoverCutHelper flow_cover_cut_helper_;
442 IntegerRoundingCutHelper integer_rounding_cut_helper_;
445 LinearConstraint cut_;
446 LinearConstraint saved_cut_;
447 LinearConstraint tmp_constraint_;
449 ScatteredIntegerVector tmp_scattered_vector_;
451 std::vector<double> tmp_lp_values_;
452 std::vector<IntegerValue> tmp_var_lbs_;
453 std::vector<IntegerValue> tmp_var_ubs_;
454 std::vector<glop::RowIndex> tmp_slack_rows_;
455 std::vector<std::pair<glop::ColIndex, IntegerValue>> tmp_terms_;
458 std::vector<std::pair<glop::RowIndex, double>> tmp_lp_multipliers_;
459 std::vector<std::pair<glop::RowIndex, IntegerValue>> tmp_integer_multipliers_;
462 mutable std::vector<std::pair<glop::RowIndex, double>> tmp_cp_multipliers_;
471 std::vector<IntegerVariable> integer_variables_;
472 absl::flat_hash_map<IntegerVariable, glop::ColIndex> mirror_lp_variable_;
476 bool objective_is_defined_ =
false;
477 IntegerVariable objective_cp_;
480 const SatParameters& parameters_;
483 IntegerTrail* integer_trail_;
484 SatSolver* sat_solver_;
486 IntegerEncoder* integer_encoder_;
487 ModelRandomGenerator* random_;
490 ImpliedBoundsProcessor implied_bounds_processor_;
494 LinearProgrammingDispatcher* dispatcher_;
496 std::vector<IntegerLiteral> integer_reason_;
497 std::vector<IntegerLiteral> deductions_;
498 std::vector<IntegerLiteral> deductions_reason_;
505 int rev_optimal_constraints_size_ = 0;
506 std::vector<std::unique_ptr<IntegerSumLE>> optimal_constraints_;
511 int lp_solution_level_ = 0;
512 bool lp_solution_is_set_ =
false;
513 bool lp_solution_is_integer_ =
false;
514 double lp_objective_;
515 std::vector<double> lp_solution_;
516 std::vector<double> lp_reduced_cost_;
521 std::vector<double> level_zero_lp_solution_;
525 bool lp_at_level_zero_is_final_ =
false;
528 LinearProgrammingConstraintLpSolution& expanded_lp_solution_;
531 bool lp_constraint_is_registered_ =
false;
533 std::vector<CutGenerator> cut_generators_;
536 bool compute_reduced_cost_averages_ =
false;
537 int num_calls_since_reduced_cost_averages_reset_ = 0;
538 std::vector<double> sum_cost_up_;
539 std::vector<double> sum_cost_down_;
540 std::vector<int> num_cost_up_;
541 std::vector<int> num_cost_down_;
542 std::vector<double> rc_scores_;
546 int rev_rc_start_ = 0;
548 std::vector<std::pair<double, int>> positions_by_decreasing_rc_score_;
551 IncrementalAverage average_degeneracy_;
552 bool is_degenerate_ =
false;
555 int branching_frequency_ = 1;
556 int64_t count_since_last_branching_ = 0;
560 int64_t total_num_simplex_iterations_ = 0;
564 int64_t total_num_cut_propagations_ = 0;
567 int64_t num_solves_ = 0;
568 std::vector<int64_t> num_solves_by_status_;
577 :
public absl::flat_hash_map<IntegerVariable,
578 LinearProgrammingConstraint*> {};
582 :
public std::vector<LinearProgrammingConstraint*> {
587 ->callbacks.push_back([
this](CpSolverResponse*
response) {
588 int64_t num_lp_iters = 0;
592 response->set_num_lp_iterations(num_lp_iters);
600 const LinearConstraint& constraint);
606 LinearConstraint* constraint);
A simple class to enforce both an elapsed time limit and a deterministic time limit in the same threa...
std::string GetDimensionString() const
double CurrentAverage() const
LinearProgrammingConstraintCollection(Model *model)
bool Propagate() override
double average_degeneracy() const
std::string DimensionString() const
double SolutionObjectiveValue() const
double GetSolutionValue(IntegerVariable variable) const
const std::vector< std::unique_ptr< IntegerSumLE > > & OptimalConstraints() const
void RegisterWith(Model *model)
int64_t total_num_simplex_iterations() const
glop::RowIndex ConstraintIndex
std::function< IntegerLiteral()> HeuristicLpReducedCostAverageBranching()
bool SolutionIsInteger() const
LinearProgrammingConstraint(Model *model, absl::Span< const IntegerVariable > vars)
IntegerSumLE * LatestOptimalConstraintOrNull() const
std::string Statistics() const
std::function< IntegerLiteral()> HeuristicLpReducedCostBinary(Model *model)
IntegerVariable ObjectiveVariable() const
void AddLinearConstraint(const LinearConstraint &ct)
bool IncrementalPropagate(const std::vector< int > &watch_indices) override
void SetLevel(int level) override
std::function< IntegerLiteral()> HeuristicLpMostInfeasibleBinary(Model *model)
const std::vector< IntegerVariable > & integer_variables() const
void SetMainObjectiveVariable(IntegerVariable ivar)
void SetObjectiveCoefficient(IntegerVariable ivar, IntegerValue coeff)
double GetSolutionReducedCost(IntegerVariable variable) const
void AddCutGenerator(CutGenerator generator)
Class that owns everything related to a particular optimization model.
void ConvertToLinearConstraint(const std::vector< IntegerVariable > &integer_variables, IntegerValue upper_bound, LinearConstraint *result)
bool Add(glop::ColIndex col, IntegerValue value)
void ClearAndResize(int size)
IntegerValue operator[](glop::ColIndex col) const
std::vector< std::pair< glop::ColIndex, IntegerValue > > GetTerms()
bool AddLinearExpressionMultiple(IntegerValue multiplier, const std::vector< std::pair< glop::ColIndex, IntegerValue >> &terms)
SharedResponseManager * response
constexpr IntegerValue kMinIntegerValue(-kMaxIntegerValue.value())
bool PossibleOverflow(const IntegerTrail &integer_trail, const LinearConstraint &constraint)
void PreventOverflow(const IntegerTrail &integer_trail, LinearConstraint *constraint)
Collection of objects used to extend the Constraint Solver library.
glop::ProblemStatus status
IntegerValue new_obj_bound
LinearProgrammingConstraintLpSolution()=default