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"
83 IntegerValue multiplier,
84 const std::vector<std::pair<glop::ColIndex, IntegerValue>>& terms);
93 const std::vector<IntegerVariable>& integer_variables,
97 std::vector<std::pair<glop::ColIndex, IntegerValue>>
GetTerms();
101 return dense_vector_[
col];
110 bool is_sparse_ =
true;
111 std::vector<glop::ColIndex> non_zeros_;
135class LinearProgrammingDispatcher;
180 return integer_variables_;
228 return total_num_simplex_iterations_;
236 if (optimal_constraints_.empty())
return nullptr;
237 return optimal_constraints_.back().get();
241 return optimal_constraints_;
247 bool BranchOnVar(IntegerVariable
var);
255 std::vector<IntegerLiteral>* integer_reason);
262 bool CreateLpFromConstraintManager();
272 bool AddCutFromConstraints(
273 const std::string&
name,
274 const std::vector<std::pair<glop::RowIndex, IntegerValue>>&
275 integer_multipliers);
278 bool PostprocessAndAddCut(
279 const std::string&
name,
const std::string& info,
280 IntegerVariable first_new_var, IntegerVariable first_slack,
281 const std::vector<ImpliedBoundsProcessor::SlackInfo>& ib_slack_infos,
286 void AddObjectiveCut();
289 void AddZeroHalfCuts();
292 void UpdateBoundsOfLpVariables();
297 bool ExactLpReasonning();
302 bool FillExactDualRayReason();
305 int64_t CalculateDegeneracy();
313 std::vector<std::pair<glop::RowIndex, IntegerValue>> ScaleLpMultiplier(
314 bool take_objective_into_account,
315 const std::vector<std::pair<glop::RowIndex, double>>& lp_multipliers,
323 bool ComputeNewLinearConstraint(
324 const std::vector<std::pair<glop::RowIndex, IntegerValue>>&
332 void AdjustNewLinearConstraint(
333 std::vector<std::pair<glop::RowIndex, IntegerValue>>* integer_multipliers,
338 using LinearExpression = std::vector<std::pair<glop::ColIndex, IntegerValue>>;
342 void ConvertToLinearConstraint(
371 void ReducedCostStrengtheningDeductions(
double cp_objective_delta);
378 glop::ColIndex GetOrCreateMirrorVariable(IntegerVariable positive_variable);
382 void UpdateAverageReducedCosts();
393 void UpdateSimplexIterationLimit(
const int64_t min_iter,
394 const int64_t max_iter);
399 static constexpr double kCpEpsilon = 1e-4;
402 static constexpr double kLpEpsilon = 1e-6;
406 static constexpr double kZeroTolerance = 1e-12;
414 struct LinearConstraintInternal {
419 LinearExpression integer_objective_;
420 IntegerValue integer_objective_offset_ = IntegerValue(0);
421 IntegerValue objective_infinity_norm_ = IntegerValue(0);
428 int64_t next_simplex_iter_ = 500;
434 ZeroHalfCutHelper zero_half_cut_helper_;
435 CoverCutHelper cover_cut_helper_;
436 IntegerRoundingCutHelper integer_rounding_cut_helper_;
437 LinearConstraint cut_;
438 LinearConstraint tmp_constraint_;
440 ScatteredIntegerVector tmp_scattered_vector_;
442 std::vector<double> tmp_lp_values_;
443 std::vector<IntegerValue> tmp_var_lbs_;
444 std::vector<IntegerValue> tmp_var_ubs_;
445 std::vector<glop::RowIndex> tmp_slack_rows_;
446 std::vector<IntegerValue> tmp_slack_bounds_;
447 std::vector<ImpliedBoundsProcessor::SlackInfo> tmp_ib_slack_infos_;
448 std::vector<std::pair<glop::ColIndex, IntegerValue>> tmp_terms_;
451 std::vector<std::pair<glop::RowIndex, double>> tmp_lp_multipliers_;
452 std::vector<std::pair<glop::RowIndex, IntegerValue>> tmp_integer_multipliers_;
455 mutable std::vector<std::pair<glop::RowIndex, double>> tmp_cp_multipliers_;
464 std::vector<IntegerVariable> integer_variables_;
465 absl::flat_hash_map<IntegerVariable, glop::ColIndex> mirror_lp_variable_;
469 bool objective_is_defined_ =
false;
470 IntegerVariable objective_cp_;
473 const SatParameters& parameters_;
476 IntegerTrail* integer_trail_;
478 IntegerEncoder* integer_encoder_;
479 ModelRandomGenerator* random_;
482 ImpliedBoundsProcessor implied_bounds_processor_;
486 LinearProgrammingDispatcher* dispatcher_;
488 std::vector<IntegerLiteral> integer_reason_;
489 std::vector<IntegerLiteral> deductions_;
490 std::vector<IntegerLiteral> deductions_reason_;
497 int rev_optimal_constraints_size_ = 0;
498 std::vector<std::unique_ptr<IntegerSumLE>> optimal_constraints_;
503 int lp_solution_level_ = 0;
504 bool lp_solution_is_set_ =
false;
505 bool lp_solution_is_integer_ =
false;
506 double lp_objective_;
507 std::vector<double> lp_solution_;
508 std::vector<double> lp_reduced_cost_;
513 std::vector<double> level_zero_lp_solution_;
517 bool lp_at_level_zero_is_final_ =
false;
520 LinearProgrammingConstraintLpSolution& expanded_lp_solution_;
523 bool lp_constraint_is_registered_ =
false;
525 std::vector<CutGenerator> cut_generators_;
528 bool compute_reduced_cost_averages_ =
false;
529 int num_calls_since_reduced_cost_averages_reset_ = 0;
530 std::vector<double> sum_cost_up_;
531 std::vector<double> sum_cost_down_;
532 std::vector<int> num_cost_up_;
533 std::vector<int> num_cost_down_;
534 std::vector<double> rc_scores_;
538 int rev_rc_start_ = 0;
540 std::vector<std::pair<double, int>> positions_by_decreasing_rc_score_;
543 IncrementalAverage average_degeneracy_;
544 bool is_degenerate_ =
false;
547 int branching_frequency_ = 1;
548 int64_t count_since_last_branching_ = 0;
552 int64_t total_num_simplex_iterations_ = 0;
555 int64_t num_solves_ = 0;
556 std::vector<int64_t> num_solves_by_status_;
565 :
public absl::flat_hash_map<IntegerVariable,
566 LinearProgrammingConstraint*> {
573 :
public std::vector<LinearProgrammingConstraint*> {
586 int num_nodes,
const std::vector<int>& tails,
const std::vector<int>& heads,
587 const std::vector<Literal>& literals, Model*
model);
594 const std::vector<int>& tails,
595 const std::vector<int>& heads,
596 const std::vector<Literal>& literals,
597 const std::vector<int64_t>& demands,
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()
bool Propagate() override
double average_degeneracy() const
std::string DimensionString() const
double SolutionObjectiveValue() const
IntegerSumLE * LatestOptimalConstraintOrNull() const
double GetSolutionValue(IntegerVariable variable) 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)
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< std::unique_ptr< IntegerSumLE > > & OptimalConstraints() const
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)
LinearProgrammingDispatcher(Model *model)
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)
bool AddLinearExpressionMultiple(IntegerValue multiplier, const std::vector< std::pair< glop::ColIndex, IntegerValue > > &terms)
const bool IsSparse() const
void ClearAndResize(int size)
IntegerValue operator[](glop::ColIndex col) const
std::vector< std::pair< glop::ColIndex, IntegerValue > > GetTerms()
CutGenerator CreateCVRPCutGenerator(int num_nodes, const std::vector< int > &tails, const std::vector< int > &heads, const std::vector< Literal > &literals, const std::vector< int64_t > &demands, int64_t capacity, Model *model)
constexpr IntegerValue kMinIntegerValue(-kMaxIntegerValue.value())
CutGenerator CreateStronglyConnectedGraphCutGenerator(int num_nodes, const std::vector< int > &tails, const std::vector< int > &heads, const std::vector< Literal > &literals, Model *model)
Collection of objects used to extend the Constraint Solver library.
glop::ProblemStatus status
IntegerValue new_obj_bound
LinearProgrammingConstraintLpSolution()