145 absl::Span<const IntegerVariable> vars);
160 objective_cp_ = ivar;
161 objective_cp_is_part_of_lp_ =
false;
162 for (
const IntegerVariable var : integer_variables_) {
163 if (var == objective_cp_) {
164 objective_cp_is_part_of_lp_ =
true;
200 return static_cast<int>(extended_integer_variables_.size());
203 return extended_integer_variables_;
217 return average_degeneracy_.CurrentAverage();
222 return total_num_simplex_iterations_;
225 return total_num_cut_propagations_;
228 return total_num_eq_propagations_;
240 return num_solves_by_status_;
244 return constraint_manager_;
249 if (optimal_constraints_.empty())
return nullptr;
250 return optimal_constraints_.back().get();
255 return optimal_constraints_;
262 watcher_->CallOnNextPropagate(watcher_id_);
269 simplex_.LoadStateForNextSolve(state_);
278 std::vector<IntegerLiteral>* integer_reason);
285 bool CreateLpFromConstraintManager();
295 bool PreprocessCut(IntegerVariable first_slack,
CutData* cut);
302 bool AddCutFromConstraints(
303 absl::string_view name,
304 absl::Span<
const std::pair<glop::RowIndex, IntegerValue>>
305 integer_multipliers);
308 bool PostprocessAndAddCut(
const std::string& name,
const std::string& info,
309 IntegerVariable first_slack,
const CutData& cut);
313 void AddObjectiveCut();
316 void AddZeroHalfCuts();
319 void UpdateBoundsOfLpVariables();
324 bool PropagateExactLpReason();
329 bool PropagateExactDualRay();
336 int64_t CalculateDegeneracy();
344 void IgnoreTrivialConstraintMultipliers(
345 std::vector<std::pair<glop::RowIndex, double>>* lp_multipliers);
346 void ScaleMultipliers(
347 absl::Span<
const std::pair<glop::RowIndex, double>> lp_multipliers,
348 bool take_objective_into_account, IntegerValue* scaling,
349 std::vector<std::pair<glop::RowIndex, IntegerValue>>* output)
const;
353 bool ScalingCanOverflow(
354 int power,
bool take_objective_into_account,
355 absl::Span<
const std::pair<glop::RowIndex, double>> multipliers,
356 int64_t overflow_cap)
const;
364 template <
bool check_overflow = true>
365 bool ComputeNewLinearConstraint(
366 absl::Span<
const std::pair<glop::RowIndex, IntegerValue>>
369 IntegerValue* upper_bound)
const;
374 void AdjustNewLinearConstraint(
375 std::vector<std::pair<glop::RowIndex, IntegerValue>>* integer_multipliers,
377 IntegerValue* upper_bound)
const;
380 using LinearExpression = std::vector<std::pair<glop::ColIndex, IntegerValue>>;
384 void ConvertToLinearConstraint(
397 void ReducedCostStrengtheningDeductions(
double cp_objective_delta);
404 glop::ColIndex GetMirrorVariable(IntegerVariable positive_variable);
408 void UpdateAverageReducedCosts();
419 void UpdateSimplexIterationLimit(int64_t min_iter, int64_t max_iter);
422 absl::Span<const glop::ColIndex> IntegerLpRowCols(glop::RowIndex row)
const;
423 absl::Span<const IntegerValue> IntegerLpRowCoeffs(glop::RowIndex row)
const;
425 void ComputeIntegerLpScalingFactors();
429 std::vector<double> row_factors_;
430 std::vector<double> col_factors_;
431 std::vector<double> col_max_;
432 std::vector<double> col_min_;
437 static constexpr double kCpEpsilon = 1e-4;
440 static constexpr double kLpEpsilon = 1e-6;
444 static constexpr double kZeroTolerance = 1e-12;
455 struct LinearConstraintInternal {
463 bool lb_is_trivial =
false;
464 bool ub_is_trivial =
false;
466 std::vector<glop::ColIndex> integer_lp_cols_;
467 std::vector<IntegerValue> integer_lp_coeffs_;
469 std::vector<glop::ColIndex> tmp_cols_;
470 std::vector<IntegerValue> tmp_coeffs_;
471 std::vector<IntegerVariable> tmp_vars_;
473 LinearExpression integer_objective_;
474 IntegerValue integer_objective_offset_ = IntegerValue(0);
475 IntegerValue objective_infinity_norm_ = IntegerValue(0);
486 int64_t next_simplex_iter_ = 500;
492 bool problem_proven_infeasible_by_cuts_ =
false;
495 ScatteredIntegerVector tmp_scattered_vector_;
497 std::vector<double> tmp_lp_values_;
498 std::vector<IntegerValue> tmp_var_lbs_;
499 std::vector<IntegerValue> tmp_var_ubs_;
500 std::vector<glop::RowIndex> tmp_slack_rows_;
501 std::vector<std::pair<glop::ColIndex, IntegerValue>> tmp_terms_;
504 std::vector<std::pair<glop::RowIndex, double>> tmp_lp_multipliers_;
505 std::vector<std::pair<glop::RowIndex, double>> tmp_cg_multipliers_;
506 std::vector<std::pair<glop::RowIndex, IntegerValue>> tmp_integer_multipliers_;
512 std::vector<IntegerVariable> integer_variables_;
513 std::vector<IntegerVariable> extended_integer_variables_;
517 std::vector<int> orbit_indices_;
521 bool objective_is_defined_ =
false;
522 bool objective_cp_is_part_of_lp_ =
false;
523 IntegerVariable objective_cp_;
530 const SatParameters& parameters_;
533 IntegerTrail* integer_trail_;
535 SatSolver* sat_solver_;
536 GenericLiteralWatcher* watcher_;
537 ProductDetector* product_detector_;
538 ObjectiveDefinition* objective_definition_;
539 SharedStatistics* shared_stats_;
540 SharedResponseManager* shared_response_manager_;
541 ModelRandomGenerator* random_;
542 LinearConstraintSymmetrizer* symmetrizer_;
543 LinearPropagator* linear_propagator_;
548 ZeroHalfCutHelper zero_half_cut_helper_;
549 CoverCutHelper cover_cut_helper_;
550 IntegerRoundingCutHelper integer_rounding_cut_helper_;
551 BoolRLTCutHelper rlt_cut_helper_;
554 ImpliedBoundsProcessor implied_bounds_processor_;
558 LinearProgrammingDispatcher* dispatcher_;
560 std::vector<IntegerLiteral> integer_reason_;
561 std::vector<IntegerLiteral> deductions_;
562 std::vector<IntegerLiteral> deductions_reason_;
569 int rev_optimal_constraints_size_ = 0;
570 std::vector<std::unique_ptr<IntegerSumLE128>> optimal_constraints_;
571 std::vector<int64_t> cumulative_optimal_constraint_sizes_;
576 int lp_solution_level_ = 0;
577 bool lp_solution_is_set_ =
false;
578 bool lp_solution_is_integer_ =
false;
579 std::vector<double> lp_solution_;
580 std::vector<double> lp_reduced_cost_;
584 int previous_level_ = 0;
585 bool lp_at_optimal_ =
false;
586 double lp_objective_lower_bound_;
591 std::vector<double> level_zero_lp_solution_;
595 bool lp_at_level_zero_is_final_ =
false;
596 int num_force_lp_call_on_next_propagate_ = 0;
599 ModelLpVariableMapping& mirror_lp_variable_;
600 ModelLpValues& expanded_lp_solution_;
601 ModelReducedCosts& expanded_reduced_costs_;
604 bool lp_constraint_is_registered_ =
false;
606 std::vector<CutGenerator> cut_generators_;
609 bool compute_reduced_cost_averages_ =
false;
610 int num_calls_since_reduced_cost_averages_reset_ = 0;
611 std::vector<double> sum_cost_up_;
612 std::vector<double> sum_cost_down_;
613 std::vector<int> num_cost_up_;
614 std::vector<int> num_cost_down_;
615 std::vector<double> rc_scores_;
619 int rev_rc_start_ = 0;
621 std::vector<std::pair<double, int>> positions_by_decreasing_rc_score_;
624 IncrementalAverage average_degeneracy_;
625 bool is_degenerate_ =
false;
629 int64_t total_num_simplex_iterations_ = 0;
633 FirstFewValues<10> reachable_;
634 int64_t total_num_cut_propagations_ = 0;
635 int64_t total_num_eq_propagations_ = 0;
638 int64_t num_lp_changes_ = 0;
641 int64_t num_solves_ = 0;
642 mutable int64_t num_adjusts_ = 0;
643 mutable int64_t num_cut_overflows_ = 0;
644 mutable int64_t num_bad_cuts_ = 0;
645 mutable int64_t num_scaling_issues_ = 0;
646 std::vector<int64_t> num_solves_by_status_;
649 bool enabled_ =
true;
652 int64_t num_root_level_skips_ = 0;
653 int64_t num_root_level_solves_ = 0;
654 double last_root_level_deterministic_duration_ = 0.0;
655 double last_root_level_deterministic_time_ = 0.0;