[CP-SAT] one more presolve rule

This commit is contained in:
Laurent Perron
2025-04-22 20:16:32 +02:00
parent 48fc2fc3d6
commit 06ee4ee6da
2 changed files with 34 additions and 1 deletions

View File

@@ -28,7 +28,7 @@
#include "absl/flags/flag.h"
#include "absl/log/check.h"
#include "absl/log/flags.h"
#include "absl/log/initialize.h"
#include "absl/log/log.h"
#include "absl/strings/match.h"

View File

@@ -5909,6 +5909,39 @@ bool CpModelPresolver::PresolveNoOverlap(ConstraintProto* ct) {
}
}
{
// Special case for "all-diff" encoded as no-overlap.
int num_size_zero_or_one = 0;
for (const int index : proto->intervals()) {
const IntervalConstraintProto& interval =
context_->working_model->constraints(index).interval();
const LinearExpressionProto& size = interval.size();
if (size.vars().empty() && size.offset() >= 0 && size.offset() <= 1) {
++num_size_zero_or_one;
} else {
break; // early abort
}
}
const int initial_num_intervals = proto->intervals().size();
if (num_size_zero_or_one == initial_num_intervals) {
// If there is only size one, we can remove the size zero as there is
// no constraint on them.
int new_size = 0;
for (const int index : proto->intervals()) {
const IntervalConstraintProto& interval =
context_->working_model->constraints(index).interval();
if (interval.size().offset() == 0) continue;
proto->set_intervals(new_size++, index);
}
if (new_size < initial_num_intervals) {
proto->mutable_intervals()->Truncate(new_size);
changed = true;
context_->UpdateRuleStats("no_overlap: removed size 0 from all diff.");
}
context_->UpdateRuleStats("TODO no_overlap: only size one !");
}
}
if (proto->intervals_size() == 1) {
context_->UpdateRuleStats("no_overlap: only one interval");
return RemoveConstraint(ct);