Skip to content

Commit 9803ccb

Browse files
committed
[CP-SAT] fix #4458; fix overflow in cumulative propagator
1 parent 0781ae7 commit 9803ccb

File tree

6 files changed

+22
-10
lines changed

6 files changed

+22
-10
lines changed

ortools/sat/cp_model_solver.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2489,11 +2489,17 @@ CpSolverResponse SolveCpModel(const CpModelProto& model_proto, Model* model) {
24892489
const CpSolverStatus presolve_status =
24902490
PresolveCpModel(context.get(), &postsolve_mapping);
24912491

2492-
// Delete the context as soon a the presolve is done. Note that only
2492+
// Delete the context as soon as the presolve is done. Note that only
24932493
// postsolve_mapping and mapping_proto are needed for postsolve.
24942494
context.reset(nullptr);
24952495

24962496
if (presolve_status != CpSolverStatus::UNKNOWN) {
2497+
if (presolve_status == CpSolverStatus::INFEASIBLE &&
2498+
hint_feasible_before_presolve &&
2499+
params.debug_crash_if_presolve_breaks_hint()) {
2500+
LOG(FATAL) << "Presolve bug: model with feasible hint found UNSAT "
2501+
"after presolve.";
2502+
}
24972503
SOLVER_LOG(logger, "Problem closed by presolve.");
24982504
CpSolverResponse status_response;
24992505
status_response.set_status(presolve_status);

ortools/sat/cumulative_energy.cc

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -529,14 +529,15 @@ bool CumulativeDualFeasibleEnergyConstraint::Propagate() {
529529
if (num_events == 0) return true;
530530
++num_calls_;
531531

532-
const IntegerValue largest_window =
533-
helper_->EndMax(helper_->TaskByDecreasingEndMax().front().task_index) -
534-
helper_->TaskByIncreasingStartMin().front().time;
535-
if (largest_window == 0) return true;
532+
const IntegerValue start_end_magnitude =
533+
std::max(IntTypeAbs(helper_->EndMax(
534+
helper_->TaskByDecreasingEndMax().front().task_index)),
535+
IntTypeAbs(helper_->TaskByIncreasingStartMin().front().time));
536+
if (start_end_magnitude == 0) return true;
536537

537538
const IntegerValue max_for_fixpoint_inverse =
538539
std::numeric_limits<IntegerValue>::max() /
539-
(num_events * capacity_max * largest_window);
540+
(num_events * capacity_max * start_end_magnitude);
540541

541542
theta_tree_.Reset(num_events);
542543

ortools/sat/diffn_util.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2008,7 +2008,7 @@ std::vector<std::pair<int, int>> FindPartialRectangleIntersectionsAlsoEmpty(
20082008
return result;
20092009
}
20102010

2011-
absl::optional<std::pair<int, int>> FindOneIntersectionIfPresent(
2011+
std::optional<std::pair<int, int>> FindOneIntersectionIfPresent(
20122012
absl::Span<const Rectangle> rectangles) {
20132013
DCHECK(
20142014
absl::c_is_sorted(rectangles, [](const Rectangle& a, const Rectangle& b) {

ortools/sat/diffn_util.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,7 @@ std::vector<std::pair<int, int>> FindPartialRectangleIntersectionsAlsoEmpty(
713713
//
714714
// If a pair {i, j} is returned, we will have i < j, and no intersection in
715715
// the subset of rectanges in [0, j).
716-
absl::optional<std::pair<int, int>> FindOneIntersectionIfPresent(
716+
std::optional<std::pair<int, int>> FindOneIntersectionIfPresent(
717717
absl::Span<const Rectangle> rectangles);
718718

719719
} // namespace sat

ortools/sat/precedences.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,10 +216,13 @@ void PrecedenceRelations::Build() {
216216

217217
// We will construct a graph with the current relation from all_relations_.
218218
// And use this to compute the "closure".
219-
// Note that the non-determinism of the arcs order shouldn't matter.
220219
CHECK(arc_offsets_.empty());
221220
graph_.ReserveArcs(2 * root_relations_.size());
222-
for (const auto [var_pair, negated_offset] : root_relations_) {
221+
std::vector<
222+
std::pair<std::pair<IntegerVariable, IntegerVariable>, IntegerValue>>
223+
root_relations_sorted(root_relations_.begin(), root_relations_.end());
224+
std::sort(root_relations_sorted.begin(), root_relations_sorted.end());
225+
for (const auto [var_pair, negated_offset] : root_relations_sorted) {
223226
// TODO(user): Support negative offset?
224227
//
225228
// Note that if we only have >= 0 ones, if we do have a cycle, we could

ortools/sat/work_assignment.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,8 @@ bool SharedTreeWorker::SyncWithSharedTree() {
820820
time_limit_->GetElapsedDeterministicTime()) {
821821
earliest_replacement_dtime_ =
822822
time_limit_->GetElapsedDeterministicTime() + 1;
823+
// Treat this as reassigning the same tree.
824+
assigned_tree_lbds_.Add(restart_policy_->LbdAverageSinceReset());
823825
}
824826
VLOG(2) << "Assigned level: " << assigned_tree_.MaxLevel() << " "
825827
<< parameters_->name();

0 commit comments

Comments
 (0)