diff --git a/ortools/sat/BUILD.bazel b/ortools/sat/BUILD.bazel index 22f0ce0ff8..06d1525a84 100644 --- a/ortools/sat/BUILD.bazel +++ b/ortools/sat/BUILD.bazel @@ -2006,6 +2006,7 @@ cc_library( "@com_google_absl//absl/log:check", "@com_google_absl//absl/random:bit_gen_ref", "@com_google_absl//absl/random:distributions", + "@com_google_absl//absl/types:span", ], ) diff --git a/ortools/sat/cp_model_symmetries.cc b/ortools/sat/cp_model_symmetries.cc index 91fabb07ce..339c9e59a5 100644 --- a/ortools/sat/cp_model_symmetries.cc +++ b/ortools/sat/cp_model_symmetries.cc @@ -327,9 +327,10 @@ std::unique_ptr GenerateGraphForSymmetryDetection( const LinearExpressionProto& target_expr = constraint.lin_max().target(); - std::vector target_color = color; - target_color.push_back(target_expr.offset()); - const int target_node = new_node(target_color); + std::vector local_color = color; + local_color.push_back(target_expr.offset()); + const int target_node = new_node(local_color); + local_color.pop_back(); for (int j = 0; j < target_expr.vars_size(); ++j) { const int var = target_expr.vars(j); @@ -339,11 +340,14 @@ std::unique_ptr GenerateGraphForSymmetryDetection( } for (int i = 0; i < constraint.lin_max().exprs_size(); ++i) { + // TODO(user): We can create a node per LinearExpressionProto instead. + // This will allow to reuse node between constraint, if they share a + // common expression. const LinearExpressionProto& expr = constraint.lin_max().exprs(i); - std::vector local_color = color; local_color.push_back(expr.offset()); const int local_node = new_node(local_color); + local_color.pop_back(); for (int j = 0; j < expr.vars().size(); ++j) { const int var = expr.vars(j); diff --git a/ortools/sat/implied_bounds.cc b/ortools/sat/implied_bounds.cc index d2a3897bc5..1ed406afab 100644 --- a/ortools/sat/implied_bounds.cc +++ b/ortools/sat/implied_bounds.cc @@ -255,7 +255,7 @@ ElementEncodings::GetElementEncodedVariables() const { // the size2 affine. std::vector TryToReconcileEncodings( const AffineExpression& size2_affine, const AffineExpression& affine, - const std::vector& affine_var_encoding, + absl::Span affine_var_encoding, bool put_affine_left_in_result, IntegerEncoder* integer_encoder) { IntegerVariable binary = size2_affine.var; std::vector terms; diff --git a/ortools/sat/pb_constraint.cc b/ortools/sat/pb_constraint.cc index 6a4553c82e..6e70663d8c 100644 --- a/ortools/sat/pb_constraint.cc +++ b/ortools/sat/pb_constraint.cc @@ -147,7 +147,7 @@ bool ApplyLiteralMapping( // TODO(user): Also check for no duplicates literals + unit tests. bool BooleanLinearExpressionIsCanonical( - const std::vector& cst) { + absl::Span cst) { Coefficient previous(1); for (LiteralWithCoeff term : cst) { if (term.coefficient < previous) return false; @@ -453,7 +453,7 @@ void UpperBoundedLinearConstraint::AddToConflict( } bool UpperBoundedLinearConstraint::HasIdenticalTerms( - const std::vector& cst) { + absl::Span cst) { if (cst.size() != literals_.size()) return false; int literal_index = 0; int coeff_index = 0; diff --git a/ortools/sat/pb_constraint.h b/ortools/sat/pb_constraint.h index 65f803d100..ba42352f69 100644 --- a/ortools/sat/pb_constraint.h +++ b/ortools/sat/pb_constraint.h @@ -127,8 +127,7 @@ Coefficient ComputeNegatedCanonicalRhs(Coefficient lower_bound, Coefficient max_value); // Returns true iff the Boolean linear expression is in canonical form. -bool BooleanLinearExpressionIsCanonical( - const std::vector& cst); +bool BooleanLinearExpressionIsCanonical(absl::Span cst); // Given a Boolean linear constraint in canonical form, simplify its // coefficients using simple heuristics. @@ -391,7 +390,7 @@ class UpperBoundedLinearConstraint { const std::vector& cst); // Returns true if the given terms are the same as the one in this constraint. - bool HasIdenticalTerms(const std::vector& cst); + bool HasIdenticalTerms(absl::Span cst); Coefficient Rhs() const { return rhs_; } // Sets the rhs of this constraint. Compute the initial threshold value using diff --git a/ortools/sat/rins.cc b/ortools/sat/rins.cc index c5bccd2736..e9576ee1b2 100644 --- a/ortools/sat/rins.cc +++ b/ortools/sat/rins.cc @@ -25,6 +25,7 @@ #include "absl/log/check.h" #include "absl/random/bit_gen_ref.h" #include "absl/random/distributions.h" +#include "absl/types/span.h" #include "ortools/sat/cp_model_mapping.h" #include "ortools/sat/integer.h" #include "ortools/sat/linear_programming_constraint.h" @@ -132,7 +133,7 @@ void FillRinsNeighborhood(const std::vector& solution, } } -void FillRensNeighborhood(const std::vector& relaxation_values, +void FillRensNeighborhood(absl::Span relaxation_values, double difficulty, absl::BitGenRef random, ReducedDomainNeighborhood& reduced_domains) { std::vector var_fractionality_pairs; diff --git a/ortools/sat/scheduling_cuts.cc b/ortools/sat/scheduling_cuts.cc index d68ae910c1..d54e878f1c 100644 --- a/ortools/sat/scheduling_cuts.cc +++ b/ortools/sat/scheduling_cuts.cc @@ -243,7 +243,7 @@ std::vector FindPossibleDemands(const EnergyEvent& event, // This generates the actual cut and compute its activity vs the // available_energy_lp. bool CutIsEfficient( - const std::vector& events, IntegerValue window_start, + absl::Span events, IntegerValue window_start, IntegerValue window_end, double available_energy_lp, const absl::StrongVector& lp_values, LinearConstraintBuilder* temp_builder) { @@ -1026,7 +1026,7 @@ namespace { // // It returns false if one event cannot start before event.start_max. bool ComputeWeightedSumOfEndMinsForOnePermutation( - const std::vector& events, IntegerValue capacity_max, + absl::Span events, IntegerValue capacity_max, IntegerValue& sum_of_ends, IntegerValue& sum_of_weighted_ends, std::vector>& profile, std::vector>& new_profile) { diff --git a/ortools/sat/symmetry_util.cc b/ortools/sat/symmetry_util.cc index 61b2950ab2..78edf8fe87 100644 --- a/ortools/sat/symmetry_util.cc +++ b/ortools/sat/symmetry_util.cc @@ -183,7 +183,7 @@ std::vector GetOrbits( } std::vector GetOrbitopeOrbits( - int n, const std::vector>& orbitope) { + int n, absl::Span> orbitope) { std::vector orbits(n, -1); for (int i = 0; i < orbitope.size(); ++i) { for (int j = 0; j < orbitope[i].size(); ++j) { diff --git a/ortools/sat/symmetry_util.h b/ortools/sat/symmetry_util.h index 4179dd63f4..f045be430e 100644 --- a/ortools/sat/symmetry_util.h +++ b/ortools/sat/symmetry_util.h @@ -59,8 +59,8 @@ std::vector GetOrbits( // Returns the orbits under the given orbitope action. // Same results format as in GetOrbits(). Note that here, the orbit index // is simply the row index of an element in the orbitope matrix. -std::vector GetOrbitopeOrbits( - int n, const std::vector>& orbitope); +std::vector GetOrbitopeOrbits(int n, + absl::Span> orbitope); // Given the generators for a permutation group of [0, n-1], update it to // a set of generators of the group stabilizing the given element. diff --git a/ortools/sat/util.cc b/ortools/sat/util.cc index 806e159e11..7e26b899bc 100644 --- a/ortools/sat/util.cc +++ b/ortools/sat/util.cc @@ -277,9 +277,9 @@ int64_t ClosestMultiple(int64_t value, int64_t base) { } bool LinearInequalityCanBeReducedWithClosestMultiple( - int64_t base, const std::vector& coeffs, - const std::vector& lbs, const std::vector& ubs, - int64_t rhs, int64_t* new_rhs) { + int64_t base, absl::Span coeffs, + absl::Span lbs, absl::Span ubs, int64_t rhs, + int64_t* new_rhs) { // Precompute some bounds for the equation base * X + error <= rhs. int64_t max_activity = 0; int64_t max_x = 0; diff --git a/ortools/sat/util.h b/ortools/sat/util.h index 21cb6a4efa..5eb7cb7c93 100644 --- a/ortools/sat/util.h +++ b/ortools/sat/util.h @@ -251,9 +251,9 @@ std::vector> AtMostOneDecomposition( // Preconditions: All coeffs are assumed to be positive. You can easily negate // all the negative coeffs and corresponding bounds before calling this. bool LinearInequalityCanBeReducedWithClosestMultiple( - int64_t base, const std::vector& coeffs, - const std::vector& lbs, const std::vector& ubs, - int64_t rhs, int64_t* new_rhs); + int64_t base, absl::Span coeffs, + absl::Span lbs, absl::Span ubs, int64_t rhs, + int64_t* new_rhs); // The model "singleton" random engine used in the solver. // diff --git a/ortools/sat/zero_half_cuts.cc b/ortools/sat/zero_half_cuts.cc index 7318d88145..0dca968f89 100644 --- a/ortools/sat/zero_half_cuts.cc +++ b/ortools/sat/zero_half_cuts.cc @@ -39,8 +39,8 @@ void ZeroHalfCutHelper::Reset(int size) { void ZeroHalfCutHelper::ProcessVariables( const std::vector& lp_values, - const std::vector& lower_bounds, - const std::vector& upper_bounds) { + absl::Span lower_bounds, + absl::Span upper_bounds) { Reset(lp_values.size()); // Shift all variables to their closest bound. diff --git a/ortools/sat/zero_half_cuts.h b/ortools/sat/zero_half_cuts.h index a94bea8723..e48e9eb90d 100644 --- a/ortools/sat/zero_half_cuts.h +++ b/ortools/sat/zero_half_cuts.h @@ -18,6 +18,7 @@ #include #include +#include "absl/types/span.h" #include "ortools/lp_data/lp_types.h" #include "ortools/sat/integer.h" #include "ortools/sat/util.h" @@ -46,8 +47,8 @@ class ZeroHalfCutHelper { // TODO(user): This is a first implementation, both the heuristic and the // code performance can probably be improved uppon. void ProcessVariables(const std::vector& lp_values, - const std::vector& lower_bounds, - const std::vector& upper_bounds); + absl::Span lower_bounds, + absl::Span upper_bounds); void AddOneConstraint(glop::RowIndex, absl::Span cols, absl::Span coeffs, IntegerValue lb, IntegerValue ub);