[CP-SAT] cleanup debug code; fix cumulative_energy_test

This commit is contained in:
Laurent Perron
2025-02-17 07:21:52 +01:00
parent 3c6408ed68
commit cc9181db9d
7 changed files with 40 additions and 45 deletions

View File

@@ -2290,7 +2290,6 @@ cc_test(
":integer_base",
":integer_search",
":intervals",
":linear_constraint",
":model",
":precedences",
":sat_base",

View File

@@ -37,7 +37,6 @@
#include "ortools/sat/integer_base.h"
#include "ortools/sat/integer_search.h"
#include "ortools/sat/intervals.h"
#include "ortools/sat/linear_constraint.h"
#include "ortools/sat/model.h"
#include "ortools/sat/precedences.h"
#include "ortools/sat/sat_base.h"
@@ -50,8 +49,6 @@ namespace operations_research {
namespace sat {
namespace {
/*
// An instance is a set of energy tasks and a capacity.
struct EnergyTask {
int start_min;
@@ -84,31 +81,24 @@ std::string InstanceDebugString(const EnergyInstance& instance) {
bool SolveUsingConstraint(const EnergyInstance& instance) {
Model model;
std::vector<IntervalVariable> intervals;
std::vector<std::vector<LiteralValueValue>> decomposed_energies;
std::vector<IntegerValue> energy_min;
std::vector<IntegerValue> energy_max;
for (const auto& task : instance.tasks) {
const IntegerVariable start_var =
model.Add(NewIntegerVariable(task.start_min, task.end_max));
const IntegerVariable end_var =
model.Add(NewIntegerVariable(task.start_min, task.end_max));
const IntegerVariable size_var =
model.Add(NewIntegerVariable(task.duration_min, task.duration_max));
if (task.is_optional) {
const Literal is_present = Literal(model.Add(NewBooleanVariable()), true);
const IntegerVariable start =
model.Add(NewIntegerVariable(task.start_min, task.end_max));
const IntegerVariable end =
model.Add(NewIntegerVariable(task.start_min, task.end_max));
const IntegerVariable duration =
model.Add(NewIntegerVariable(task.duration_min, task.duration_max));
intervals.push_back(
model.Add(NewOptionalInterval(start, end, duration, is_present)));
intervals.push_back(model.Add(
NewOptionalInterval(start_var, end_var, size_var, is_present)));
} else {
intervals.push_back(model.Add(NewIntervalWithVariableSize(
task.start_min, task.end_max, task.duration_min, task.duration_max)));
intervals.push_back(model.Add(NewInterval(start_var, end_var, size_var)));
}
std::vector<Literal> energy_literals;
std::vector<LiteralValueValue> energy_literals_values_values;
for (int e = task.energy_min; e <= task.energy_max; ++e) {
const Literal lit = Literal(model.Add(NewBooleanVariable()), true);
energy_literals.push_back(lit);
energy_literals_values_values.push_back({lit, e, 1});
}
model.Add(ExactlyOneConstraint(energy_literals));
decomposed_energies.push_back(energy_literals_values_values);
energy_min.push_back(task.energy_min);
energy_max.push_back(task.energy_max);
}
const AffineExpression capacity(
@@ -118,7 +108,7 @@ bool SolveUsingConstraint(const EnergyInstance& instance) {
SchedulingConstraintHelper* helper = repo->GetOrCreateHelper(intervals);
SchedulingDemandHelper* demands_helper =
new SchedulingDemandHelper({}, helper, &model);
demands_helper->OverrideDecomposedEnergies(decomposed_energies);
demands_helper->OverrideEnergyBounds(energy_min, energy_max);
model.TakeOwnership(demands_helper);
AddCumulativeOverloadChecker(capacity, helper, demands_helper, &model);
@@ -266,8 +256,6 @@ TEST(CumulativeEnergyTest, CompareToNaiveModel) {
}
}
*/
struct CumulativeTasks {
int64_t duration;
int64_t demand;

View File

@@ -200,7 +200,7 @@ class IntegerEncoder {
IntegerValue value) const;
// Advanced usage. It is more efficient to create the associated literals in
// order, but it might be anoying to do so. Instead, you can first call
// order, but it might be annoying to do so. Instead, you can first call
// DisableImplicationBetweenLiteral() and when you are done creating all the
// associated literals, you can call (only at level zero)
// AddAllImplicationsBetweenAssociatedLiterals() which will also turn back on
@@ -318,7 +318,7 @@ class IntegerEncoder {
// corresponding to the same variable).
//
// Note that we only keep this for positive variable.
// The one for the negation can be infered by it.
// The one for the negation can be inferred by it.
//
// Like x >= 1 x >= 4 x >= 5
// Correspond to x <= 0 x <= 3 x <= 4

View File

@@ -1323,9 +1323,6 @@ CtEvent CopyAndTrimEventAfter(const CtEvent& old_event, IntegerValue time,
event.use_energy = event.energy_min > simple_energy_min;
}
event.x_start_min = time;
event.source.clear();
event.source.push_back(old_event);
event.trim_date = time;
return event;
}
@@ -1514,10 +1511,6 @@ void GenerateCompletionTimeCutsWithEnergy(absl::string_view cut_name,
<< "simple_min_shape_area: "
<< event.energy_min * event.x_size_min;
LOG(INFO) << " event = " << event.DebugString();
if (event.lifted) {
LOG(INFO) << "old_event = " << event.source.front().DebugString();
LOG(INFO) << " trim_date: " << event.trim_date;
}
}
CHECK_GE(min_shape_area, event.energy_min * event.x_size_min);

View File

@@ -146,9 +146,6 @@ struct CtEvent : BaseEvent {
bool y_size_is_fixed = false;
std::string DebugString() const;
std::vector<CtEvent> source;
IntegerValue trim_date = 0;
};
// Computes the minimum sum of the end min and the minimum sum of the end min

View File

@@ -799,8 +799,8 @@ bool SchedulingDemandHelper::CacheAllEnergyValues() {
return false;
}
// Checks the propagation of the consistency of implied values and
// literals.
// Checks the consistency of implied values and literal values with the
// cached bounds of the size and demand expressions.
int new_size = 0;
IntegerValue min_size = kMaxIntegerValue;
IntegerValue max_size = kMinIntegerValue;
@@ -838,14 +838,22 @@ bool SchedulingDemandHelper::CacheAllEnergyValues() {
}
}
cached_energies_min_[t] =
std::max(SimpleEnergyMin(t), DecomposedEnergyMin(t));
if (t < override_energy_min_.size()) {
cached_energies_min_[t] = override_energy_min_[t];
} else {
cached_energies_min_[t] =
std::max(SimpleEnergyMin(t), DecomposedEnergyMin(t));
}
if (cached_energies_min_[t] <= kMinIntegerValue) return false;
energy_is_quadratic_[t] =
decomposed_energies_[t].empty() && !demands_.empty() &&
!integer_trail_->IsFixed(demands_[t]) && !helper_->SizeIsFixed(t);
cached_energies_max_[t] =
std::min(SimpleEnergyMax(t), DecomposedEnergyMax(t));
if (t < override_energy_max_.size()) {
cached_energies_max_[t] = override_energy_max_[t];
} else {
cached_energies_max_[t] =
std::min(SimpleEnergyMax(t), DecomposedEnergyMax(t));
}
if (cached_energies_max_[t] >= kMaxIntegerValue) return false;
}

View File

@@ -551,6 +551,12 @@ class SchedulingDemandHelper {
// Visible for testing.
void OverrideDecomposedEnergies(
const std::vector<std::vector<LiteralValueValue>>& energies);
void OverrideEnergyBounds(const std::vector<IntegerValue>& energy_min,
const std::vector<IntegerValue>& energy_max) {
override_energy_min_ = energy_min;
override_energy_max_ = energy_max;
}
// Returns the decomposed energy terms compatible with the current literal
// assignment. It must not be used to create reasons if not at level 0.
// It returns en empty vector if the decomposed energy is not available.
@@ -583,6 +589,10 @@ class SchedulingDemandHelper {
// A representation of the energies as a set of alternative.
// If subvector is empty, we don't have this representation.
std::vector<std::vector<LiteralValueValue>> decomposed_energies_;
// Override energy bounds.
std::vector<IntegerValue> override_energy_min_;
std::vector<IntegerValue> override_energy_max_;
};
// =============================================================================