144 absl::Span<const IntegerVariable> vars);
187 return static_cast<int>(integer_variables_.size());
190 return integer_variables_;
208 return total_num_simplex_iterations_;
211 return total_num_cut_propagations_;
214 return total_num_eq_propagations_;
226 return num_solves_by_status_;
230 return constraint_manager_;
235 if (optimal_constraints_.empty())
return nullptr;
236 return optimal_constraints_.back().get();
241 return optimal_constraints_;
264 std::vector<IntegerLiteral>* integer_reason);
271 bool CreateLpFromConstraintManager();
281 bool PreprocessCut(IntegerVariable first_slack,
CutData* cut);
288 bool AddCutFromConstraints(
289 absl::string_view
name,
290 absl::Span<
const std::pair<glop::RowIndex, IntegerValue>>
291 integer_multipliers);
294 bool PostprocessAndAddCut(
const std::string&
name,
const std::string& info,
295 IntegerVariable first_slack,
const CutData& cut);
299 void AddObjectiveCut();
302 void AddZeroHalfCuts();
305 void UpdateBoundsOfLpVariables();
310 bool PropagateExactLpReason();
315 bool PropagateExactDualRay();
322 int64_t CalculateDegeneracy();
330 std::vector<std::pair<glop::RowIndex, IntegerValue>> ScaleLpMultiplier(
331 bool take_objective_into_account,
bool ignore_trivial_constraints,
332 const std::vector<std::pair<glop::RowIndex, double>>& lp_multipliers,
333 IntegerValue* scaling,
334 int64_t overflow_cap = std::numeric_limits<int64_t>::max())
const;
338 bool ScalingCanOverflow(
339 int power,
bool take_objective_into_account,
340 absl::Span<
const std::pair<glop::RowIndex, double>> multipliers,
341 int64_t overflow_cap)
const;
349 template <
bool check_overflow = true>
350 bool ComputeNewLinearConstraint(
351 absl::Span<
const std::pair<glop::RowIndex, IntegerValue>>
359 void AdjustNewLinearConstraint(
360 std::vector<std::pair<glop::RowIndex, IntegerValue>>* integer_multipliers,
365 using LinearExpression = std::vector<std::pair<glop::ColIndex, IntegerValue>>;
369 void ConvertToLinearConstraint(
382 void ReducedCostStrengtheningDeductions(
double cp_objective_delta);
389 glop::ColIndex GetMirrorVariable(IntegerVariable positive_variable);
393 void UpdateAverageReducedCosts();
404 void UpdateSimplexIterationLimit(int64_t min_iter, int64_t max_iter);
407 absl::Span<const glop::ColIndex> IntegerLpRowCols(glop::RowIndex
row)
const;
408 absl::Span<const IntegerValue> IntegerLpRowCoeffs(glop::RowIndex
row)
const;
413 static constexpr double kCpEpsilon = 1e-4;
416 static constexpr double kLpEpsilon = 1e-6;
420 static constexpr double kZeroTolerance = 1e-12;
431 struct LinearConstraintInternal {
439 bool lb_is_trivial =
false;
440 bool ub_is_trivial =
false;
442 std::vector<glop::ColIndex> integer_lp_cols_;
443 std::vector<IntegerValue> integer_lp_coeffs_;
445 std::vector<glop::ColIndex> tmp_cols_;
446 std::vector<IntegerValue> tmp_coeffs_;
448 LinearExpression integer_objective_;
449 IntegerValue integer_objective_offset_ = IntegerValue(0);
450 IntegerValue objective_infinity_norm_ = IntegerValue(0);
456 glop::GlopParameters simplex_params_;
460 int64_t next_simplex_iter_ = 500;
466 ZeroHalfCutHelper zero_half_cut_helper_;
467 CoverCutHelper cover_cut_helper_;
468 IntegerRoundingCutHelper integer_rounding_cut_helper_;
470 bool problem_proven_infeasible_by_cuts_ =
false;
473 ScatteredIntegerVector tmp_scattered_vector_;
475 std::vector<double> tmp_lp_values_;
476 std::vector<IntegerValue> tmp_var_lbs_;
477 std::vector<IntegerValue> tmp_var_ubs_;
478 std::vector<glop::RowIndex> tmp_slack_rows_;
479 std::vector<std::pair<glop::ColIndex, IntegerValue>> tmp_terms_;
482 std::vector<std::pair<glop::RowIndex, double>> tmp_lp_multipliers_;
483 std::vector<std::pair<glop::RowIndex, IntegerValue>> tmp_integer_multipliers_;
486 mutable std::vector<std::pair<glop::RowIndex, double>> tmp_cp_multipliers_;
495 std::vector<IntegerVariable> integer_variables_;
496 absl::flat_hash_map<IntegerVariable, glop::ColIndex> mirror_lp_variable_;
500 bool objective_is_defined_ =
false;
501 IntegerVariable objective_cp_;
508 const SatParameters& parameters_;
511 IntegerTrail* integer_trail_;
513 GenericLiteralWatcher* watcher_;
514 IntegerEncoder* integer_encoder_;
515 ProductDetector* product_detector_;
516 ObjectiveDefinition* objective_definition_;
517 SharedStatistics* shared_stats_;
518 SharedResponseManager* shared_response_manager_;
519 ModelRandomGenerator* random_;
523 BoolRLTCutHelper rlt_cut_helper_;
526 ImpliedBoundsProcessor implied_bounds_processor_;
530 LinearProgrammingDispatcher* dispatcher_;
532 std::vector<IntegerLiteral> integer_reason_;
533 std::vector<IntegerLiteral> deductions_;
534 std::vector<IntegerLiteral> deductions_reason_;
541 int rev_optimal_constraints_size_ = 0;
542 std::vector<std::unique_ptr<IntegerSumLE128>> optimal_constraints_;
543 std::vector<int64_t> cumulative_optimal_constraint_sizes_;
548 int lp_solution_level_ = 0;
549 bool lp_solution_is_set_ =
false;
550 bool lp_solution_is_integer_ =
false;
551 std::vector<double> lp_solution_;
552 std::vector<double> lp_reduced_cost_;
556 int previous_level_ = 0;
557 bool lp_at_optimal_ =
false;
558 double lp_objective_lower_bound_;
563 std::vector<double> level_zero_lp_solution_;
567 bool lp_at_level_zero_is_final_ =
false;
570 ModelLpValues& expanded_lp_solution_;
573 bool lp_constraint_is_registered_ =
false;
575 std::vector<CutGenerator> cut_generators_;
578 bool compute_reduced_cost_averages_ =
false;
579 int num_calls_since_reduced_cost_averages_reset_ = 0;
580 std::vector<double> sum_cost_up_;
581 std::vector<double> sum_cost_down_;
582 std::vector<int> num_cost_up_;
583 std::vector<int> num_cost_down_;
584 std::vector<double> rc_scores_;
588 int rev_rc_start_ = 0;
590 std::vector<std::pair<double, int>> positions_by_decreasing_rc_score_;
593 IncrementalAverage average_degeneracy_;
594 bool is_degenerate_ =
false;
598 int64_t total_num_simplex_iterations_ = 0;
602 FirstFewValues<10> reachable_;
603 int64_t total_num_cut_propagations_ = 0;
604 int64_t total_num_eq_propagations_ = 0;
607 int64_t num_lp_changes_ = 0;
610 int64_t num_solves_ = 0;
611 mutable int64_t num_adjusts_ = 0;
612 mutable int64_t num_cut_overflows_ = 0;
613 mutable int64_t num_bad_cuts_ = 0;
614 mutable int64_t num_scaling_issues_ = 0;
615 std::vector<int64_t> num_solves_by_status_;
618 bool enabled_ =
true;