diff --git a/ortools/sat/cumulative_energy_test.cc b/ortools/sat/cumulative_energy_test.cc index 2252474527..a8b56e9905 100644 --- a/ortools/sat/cumulative_energy_test.cc +++ b/ortools/sat/cumulative_energy_test.cc @@ -82,13 +82,8 @@ std::string InstanceDebugString(const EnergyInstance& instance) { bool SolveUsingConstraint(const EnergyInstance& instance) { Model model; std::vector intervals; - std::vector energies; + std::vector> decomposed_energies; for (const auto& task : instance.tasks) { - LinearExpression energy; - energy.vars.push_back( - model.Add(NewIntegerVariable(task.energy_min, task.energy_max))); - energy.coeffs.push_back(IntegerValue(1)); - energies.push_back(energy); if (task.is_optional) { const Literal is_present = Literal(model.Add(NewBooleanVariable()), true); const IntegerVariable start = @@ -103,6 +98,15 @@ bool SolveUsingConstraint(const EnergyInstance& instance) { intervals.push_back(model.Add(NewIntervalWithVariableSize( task.start_min, task.end_max, task.duration_min, task.duration_max))); } + std::vector energy_literals; + std::vector 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); } const AffineExpression capacity( @@ -112,7 +116,7 @@ bool SolveUsingConstraint(const EnergyInstance& instance) { SchedulingConstraintHelper* helper = repo->GetOrCreateHelper(intervals); SchedulingDemandHelper* demands_helper = new SchedulingDemandHelper({}, helper, &model); - demands_helper->OverrideLinearizedEnergies(energies); + demands_helper->OverrideDecomposedEnergies(decomposed_energies); model.TakeOwnership(demands_helper); AddCumulativeOverloadChecker(capacity, helper, demands_helper, &model); diff --git a/ortools/sat/scheduling_helpers.cc b/ortools/sat/scheduling_helpers.cc index b1307e2e62..dd80a995fa 100644 --- a/ortools/sat/scheduling_helpers.cc +++ b/ortools/sat/scheduling_helpers.cc @@ -720,7 +720,6 @@ SchedulingDemandHelper::SchedulingDemandHelper( demands_(demands.begin(), demands.end()), helper_(helper) { const int num_tasks = helper->NumTasks(); - linearized_energies_.resize(num_tasks); decomposed_energies_.resize(num_tasks); cached_energies_min_.resize(num_tasks, kMinIntegerValue); cached_energies_max_.resize(num_tasks, kMaxIntegerValue); @@ -747,11 +746,6 @@ IntegerValue SchedulingDemandHelper::SimpleEnergyMin(int t) const { return CapProdI(DemandMin(t), helper_->SizeMin(t)); } -IntegerValue SchedulingDemandHelper::LinearEnergyMin(int t) const { - if (!linearized_energies_[t].has_value()) return kMinIntegerValue; - return linearized_energies_[t]->Min(*integer_trail_); -} - IntegerValue SchedulingDemandHelper::DecomposedEnergyMin(int t) const { if (decomposed_energies_[t].empty()) return kMinIntegerValue; IntegerValue result = kMaxIntegerValue; @@ -771,11 +765,6 @@ IntegerValue SchedulingDemandHelper::SimpleEnergyMax(int t) const { return CapProdI(DemandMax(t), helper_->SizeMax(t)); } -IntegerValue SchedulingDemandHelper::LinearEnergyMax(int t) const { - if (!linearized_energies_[t].has_value()) return kMaxIntegerValue; - return linearized_energies_[t]->Max(*integer_trail_); -} - IntegerValue SchedulingDemandHelper::DecomposedEnergyMax(int t) const { if (decomposed_energies_[t].empty()) return kMaxIntegerValue; IntegerValue result = kMinIntegerValue; @@ -806,14 +795,14 @@ bool SchedulingDemandHelper::CacheAllEnergyValues() { decomposed_energies_[t].resize(new_size); } - cached_energies_min_[t] = std::max( - {SimpleEnergyMin(t), LinearEnergyMin(t), DecomposedEnergyMin(t)}); + 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), LinearEnergyMax(t), DecomposedEnergyMax(t)}); + cached_energies_max_[t] = + std::min(SimpleEnergyMax(t), DecomposedEnergyMax(t)); if (cached_energies_max_[t] >= kMaxIntegerValue) return false; } @@ -849,14 +838,6 @@ bool SchedulingDemandHelper::DecreaseEnergyMax(int t, IntegerValue value) { if (!helper_->PushLiteral(lit.Negated())) return false; } } - } else if (linearized_energies_[t].has_value() && - linearized_energies_[t]->vars.size() == 1) { - const LinearExpression& e = linearized_energies_[t].value(); - const AffineExpression affine_energy(e.vars[0], e.coeffs[0], e.offset); - const IntegerLiteral deduction = affine_energy.LowerOrEqual(value); - if (!helper_->PushIntegerLiteralIfTaskPresent(t, deduction)) { - return false; - } } else { // TODO(user): Propagate if possible. VLOG(3) << "Cumulative energy missed propagation"; @@ -900,12 +881,6 @@ void SchedulingDemandHelper::AddEnergyMinReason(int t) { } else if (SimpleEnergyMin(t) >= value) { AddDemandMinReason(t); helper_->AddSizeMinReason(t); - } else { - DCHECK_GE(LinearEnergyMin(t), value); - for (const IntegerVariable var : linearized_energies_[t]->vars) { - helper_->MutableIntegerReason()->push_back( - integer_trail_->LowerBoundAsLiteral(var)); - } } } @@ -927,21 +902,6 @@ bool SchedulingDemandHelper::AddLinearizedDemand( return true; } -void SchedulingDemandHelper::OverrideLinearizedEnergies( - absl::Span energies) { - const int num_tasks = energies.size(); - DCHECK_EQ(num_tasks, helper_->NumTasks()); - linearized_energies_.resize(num_tasks); - for (int t = 0; t < num_tasks; ++t) { - linearized_energies_[t] = energies[t]; - if (DEBUG_MODE) { - for (const IntegerValue coeff : linearized_energies_[t]->coeffs) { - DCHECK_GE(coeff, 0); - } - } - } -} - std::vector SchedulingDemandHelper::FilteredDecomposedEnergy( int index) { if (decomposed_energies_[index].empty()) return {}; diff --git a/ortools/sat/scheduling_helpers.h b/ortools/sat/scheduling_helpers.h index 626503c445..b4353868f8 100644 --- a/ortools/sat/scheduling_helpers.h +++ b/ortools/sat/scheduling_helpers.h @@ -549,7 +549,6 @@ class SchedulingDemandHelper { } // Visible for testing. - void OverrideLinearizedEnergies(absl::Span energies); void OverrideDecomposedEnergies( const std::vector>& energies); // Returns the decomposed energy terms compatible with the current literal @@ -565,9 +564,7 @@ class SchedulingDemandHelper { private: IntegerValue SimpleEnergyMin(int t) const; - IntegerValue LinearEnergyMin(int t) const; IntegerValue SimpleEnergyMax(int t) const; - IntegerValue LinearEnergyMax(int t) const; IntegerValue DecomposedEnergyMin(int t) const; IntegerValue DecomposedEnergyMax(int t) const; @@ -586,10 +583,6 @@ class SchedulingDemandHelper { // A representation of the energies as a set of alternative. // If subvector is empty, we don't have this representation. std::vector> decomposed_energies_; - - // A representation of the energies as a set of linear expression. - // If the optional is not set, we don't have this representation. - std::vector> linearized_energies_; }; // =============================================================================