[CP-SAT] more defensive coding

This commit is contained in:
Laurent Perron
2024-11-18 15:33:09 +01:00
parent c37d185d6b
commit b7a1bdcff2
2 changed files with 23 additions and 9 deletions

View File

@@ -5785,7 +5785,8 @@ bool CpModelPresolver::PresolveNoOverlap2D(int /*c*/, ConstraintProto* ct) {
// thus to check whether a graph is fully connected we must check also the
// size of the unique component.
const bool is_fully_connected =
components.size() == 1 && components[0].size() == active_boxes.size();
(components.size() == 1 && components[0].size() == active_boxes.size()) ||
(active_boxes.size() <= 1);
if (!is_fully_connected) {
for (const absl::Span<int> boxes : components) {
if (boxes.size() <= 1) continue;

View File

@@ -993,16 +993,29 @@ void AppendNoOverlap2dRelaxation(const ConstraintProto& ct, Model* model,
std::vector<AffineExpression> x_sizes;
std::vector<AffineExpression> y_sizes;
for (int i = 0; i < ct.no_overlap_2d().x_intervals_size(); ++i) {
const IntegerValue curr_x_min = integer_trail->LevelZeroLowerBound(
intervals_repository->Start(x_intervals[i]));
const IntegerValue curr_x_max = integer_trail->LevelZeroUpperBound(
intervals_repository->End(x_intervals[i]));
const IntegerValue curr_y_min = integer_trail->LevelZeroLowerBound(
intervals_repository->Start(y_intervals[i]));
const IntegerValue curr_y_max = integer_trail->LevelZeroUpperBound(
intervals_repository->End(y_intervals[i]));
if (curr_x_min > curr_x_max || curr_y_min > curr_y_max) {
// This can happen if the box must be absent.
continue;
}
x_sizes.push_back(intervals_repository->Size(x_intervals[i]));
y_sizes.push_back(intervals_repository->Size(y_intervals[i]));
x_min = std::min(x_min, integer_trail->LevelZeroLowerBound(
intervals_repository->Start(x_intervals[i])));
x_max = std::max(x_max, integer_trail->LevelZeroUpperBound(
intervals_repository->End(x_intervals[i])));
y_min = std::min(y_min, integer_trail->LevelZeroLowerBound(
intervals_repository->Start(y_intervals[i])));
y_max = std::max(y_max, integer_trail->LevelZeroUpperBound(
intervals_repository->End(y_intervals[i])));
x_min = std::min(x_min, curr_x_min);
x_max = std::max(x_max, curr_x_max);
y_min = std::min(y_min, curr_y_min);
y_max = std::max(y_max, curr_y_max);
}
if (x_min > x_max || y_min > y_max) {
// All boxes must be absent.
return;
}
const IntegerValue max_area =