diff --git a/ortools/sat/BUILD.bazel b/ortools/sat/BUILD.bazel index cafe9924f9..e67d724437 100644 --- a/ortools/sat/BUILD.bazel +++ b/ortools/sat/BUILD.bazel @@ -3445,6 +3445,7 @@ cc_library( "//ortools/base:stl_util", "//ortools/graph:connected_components", "//ortools/util:adaptative_parameter_value", + "//ortools/util:bitset", "//ortools/util:integer_pq", "//ortools/util:saturated_arithmetic", "//ortools/util:sorted_interval_list", diff --git a/ortools/sat/all_different.cc b/ortools/sat/all_different.cc index 00d619246a..8c76822a8c 100644 --- a/ortools/sat/all_different.cc +++ b/ortools/sat/all_different.cc @@ -443,8 +443,7 @@ bool AllDifferentConstraint::Propagate() { } AllDifferentBoundsPropagator::AllDifferentBoundsPropagator( - const std::vector& expressions, - IntegerTrail* integer_trail) + absl::Span expressions, IntegerTrail* integer_trail) : integer_trail_(integer_trail) { CHECK(!expressions.empty()); diff --git a/ortools/sat/all_different.h b/ortools/sat/all_different.h index 743ffc8ebf..38976b05ff 100644 --- a/ortools/sat/all_different.h +++ b/ortools/sat/all_different.h @@ -150,7 +150,7 @@ class AllDifferentConstraint : PropagatorInterface { // https://cs.uwaterloo.ca/~vanbeek/Publications/ijcai03_TR.pdf class AllDifferentBoundsPropagator : public PropagatorInterface { public: - AllDifferentBoundsPropagator(const std::vector& expressions, + AllDifferentBoundsPropagator(absl::Span expressions, IntegerTrail* integer_trail); // This type is neither copyable nor movable. diff --git a/ortools/sat/cp_model_lns.cc b/ortools/sat/cp_model_lns.cc index aa793c6681..36323be3e1 100644 --- a/ortools/sat/cp_model_lns.cc +++ b/ortools/sat/cp_model_lns.cc @@ -58,6 +58,7 @@ #include "ortools/sat/synchronization.h" #include "ortools/sat/util.h" #include "ortools/util/adaptative_parameter_value.h" +#include "ortools/util/bitset.h" #include "ortools/util/integer_pq.h" #include "ortools/util/saturated_arithmetic.h" #include "ortools/util/sorted_interval_list.h" @@ -949,7 +950,8 @@ NeighborhoodGeneratorHelper::GetSchedulingPrecedences( return result; } -std::vector> NeighborhoodGeneratorHelper::GetRoutingPaths( +std::vector> +NeighborhoodGeneratorHelper::GetRoutingPathLiterals( const CpSolverResponse& initial_solution) const { struct HeadAndArcLiteral { int head; @@ -2596,7 +2598,7 @@ Neighborhood RoutingRandomNeighborhoodGenerator::Generate( const CpSolverResponse& initial_solution, SolveData& data, absl::BitGenRef random) { const std::vector> all_paths = - helper_.GetRoutingPaths(initial_solution); + helper_.GetRoutingPathLiterals(initial_solution); // Collect all unique variables. absl::flat_hash_set all_path_variables; @@ -2617,7 +2619,7 @@ Neighborhood RoutingPathNeighborhoodGenerator::Generate( const CpSolverResponse& initial_solution, SolveData& data, absl::BitGenRef random) { std::vector> all_paths = - helper_.GetRoutingPaths(initial_solution); + helper_.GetRoutingPathLiterals(initial_solution); // Collect all unique variables. absl::flat_hash_set all_path_variables; @@ -2663,7 +2665,7 @@ Neighborhood RoutingFullPathNeighborhoodGenerator::Generate( const CpSolverResponse& initial_solution, SolveData& data, absl::BitGenRef random) { std::vector> all_paths = - helper_.GetRoutingPaths(initial_solution); + helper_.GetRoutingPathLiterals(initial_solution); // Remove a corner case where all paths are empty. if (all_paths.empty()) { return helper_.NoNeighborhood(); diff --git a/ortools/sat/cp_model_lns.h b/ortools/sat/cp_model_lns.h index 76a83bb4bf..2972bb319f 100644 --- a/ortools/sat/cp_model_lns.h +++ b/ortools/sat/cp_model_lns.h @@ -15,6 +15,7 @@ #define OR_TOOLS_SAT_CP_MODEL_LNS_H_ #include +#include #include #include #include @@ -39,6 +40,7 @@ #include "ortools/sat/synchronization.h" #include "ortools/sat/util.h" #include "ortools/util/adaptative_parameter_value.h" +#include "ortools/util/bitset.h" namespace operations_research { namespace sat { @@ -250,7 +252,7 @@ class NeighborhoodGeneratorHelper : public SubSolver { // self-looping arcs. Path are sorted, starting from the arc with the lowest // tail index, and going in sequence up to the last arc before the circuit is // closed. Each entry correspond to the arc literal on the circuit. - std::vector> GetRoutingPaths( + std::vector> GetRoutingPathLiterals( const CpSolverResponse& initial_solution) const; // Returns all precedences extracted from the scheduling constraint and the diff --git a/ortools/sat/cp_model_solver.cc b/ortools/sat/cp_model_solver.cc index b7b4ea14b7..ca1e5de76b 100644 --- a/ortools/sat/cp_model_solver.cc +++ b/ortools/sat/cp_model_solver.cc @@ -818,6 +818,10 @@ void RestrictObjectiveUsingHint(CpModelProto* model_proto) { bool SolutionHintIsCompleteAndFeasible( const CpModelProto& model_proto, SolverLogger* logger = nullptr, SharedResponseManager* manager = nullptr) { + if (!model_proto.has_solution_hint() && model_proto.variables_size() > 0) { + return false; + } + int num_active_variables = 0; int num_hinted_variables = 0; for (int var = 0; var < model_proto.variables_size(); ++var) { diff --git a/ortools/sat/linear_relaxation.cc b/ortools/sat/linear_relaxation.cc index edc222ad26..b1c711d4d9 100644 --- a/ortools/sat/linear_relaxation.cc +++ b/ortools/sat/linear_relaxation.cc @@ -1059,7 +1059,8 @@ void AppendNoOverlap2dRelaxation(const ConstraintProto& ct, Model* model, const IntegerValue area_min = integer_trail->LevelZeroLowerBound(x_sizes[i]) * integer_trail->LevelZeroLowerBound(y_sizes[i]); - if (area_min != 0) { + if (area_min > 0) { + // Note that intervals that must be absent can have negative sizes. // Not including the term if we don't have a view is ok. (void)lc.AddLiteralTerm(presence_literal, area_min); }