Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
cumulative_energy.h
Go to the documentation of this file.
1// Copyright 2010-2024 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14#ifndef OR_TOOLS_SAT_CUMULATIVE_ENERGY_H_
15#define OR_TOOLS_SAT_CUMULATIVE_ENERGY_H_
16
17#include <cstdint>
18#include <functional>
19#include <utility>
20#include <vector>
21
22#include "absl/types/span.h"
24#include "ortools/sat/integer.h"
26#include "ortools/sat/model.h"
29#include "ortools/sat/util.h"
30
31namespace operations_research {
32namespace sat {
33
34// Enforces the existence of a preemptive schedule where every task is executed
35// inside its interval, using energy units of the resource during execution.
36//
37// Important: This only uses the energies min/max and not the actual demand
38// of a task. It can thus be used in some non-conventional situation.
39//
40// All energy expression are assumed to take a non-negative value;
41// if the energy of a task is 0, the task can run anywhere.
42// The schedule never uses more than capacity units of energy at a given time.
43//
44// This is mathematically equivalent to making a model with energy(task)
45// different tasks with demand and size 1, but is much more efficient,
46// since it uses O(|tasks|) variables instead of O(sum_{task} |energy(task)|).
47void AddCumulativeOverloadChecker(AffineExpression capacity,
48 SchedulingConstraintHelper* helper,
49 SchedulingDemandHelper* demands,
50 Model* model);
51
52// Same as above, but applying a Dual Feasible Function (also known as a
53// conservative scale) before looking for overload.
54void AddCumulativeOverloadCheckerDff(AffineExpression capacity,
55 SchedulingConstraintHelper* helper,
56 SchedulingDemandHelper* demands,
57 Model* model);
58
59// Implementation of AddCumulativeOverloadChecker().
61 public:
65
66 bool Propagate() final;
68
69 private:
70 const AffineExpression capacity_;
71 IntegerTrail* integer_trail_;
73 SchedulingDemandHelper* demands_;
74
76
77 // Task characteristics.
78 std::vector<int> task_to_start_event_;
79
80 // Start event characteristics, by nondecreasing start time.
81 std::vector<TaskTime> start_event_task_time_;
82 std::vector<bool> start_event_is_present_;
83};
84
85// Given that the "tasks" are part of a cumulative constraint, this adds a
86// constraint that propagate the fact that: var >= max(end of substasks) +
87// offset.
88//
89// TODO(user): I am not sure this is the best way, but it does at least push
90// the level zero bound on the large cumulative instances.
92 public:
94 AffineExpression capacity,
95 const std::vector<int>& subtasks,
96 absl::Span<const IntegerValue> offsets,
99 Model* model);
100
101 bool Propagate() final;
102 void RegisterWith(GenericLiteralWatcher* watcher);
103
104 private:
105 const IntegerVariable var_to_push_;
106 const AffineExpression capacity_;
107 const std::vector<int> subtasks_;
108
109 // Computed at construction time, this is const.
110 std::vector<bool> is_in_subtasks_;
111 std::vector<IntegerValue> task_offsets_;
112
113 // Temporary data used by the algorithm.
115 std::vector<std::pair<IntegerValue, IntegerValue>> energy_changes_;
116
117 IntegerTrail* integer_trail_;
119 SchedulingDemandHelper* demands_;
120};
121
122// Implementation of AddCumulativeOverloadCheckerDff().
124 public:
127 SchedulingDemandHelper* demands,
128 Model* model);
129
131
132 bool Propagate() final;
133 void RegisterWith(GenericLiteralWatcher* watcher);
134
135 private:
136 bool FindAndPropagateConflict(IntegerValue window_start,
137 IntegerValue window_end);
138
139 ModelRandomGenerator* random_;
140 SharedStatistics* shared_stats_;
141 OrthogonalPackingInfeasibilityDetector opp_infeasibility_detector_;
142 const AffineExpression capacity_;
143 IntegerTrail* integer_trail_;
145 SchedulingDemandHelper* demands_;
146
148
149 // Task characteristics.
150 std::vector<int> task_to_start_event_;
151
152 // Start event characteristics, by nondecreasing start time.
153 std::vector<TaskTime> start_event_task_time_;
154
155 int64_t num_calls_ = 0;
156 int64_t num_conflicts_ = 0;
157 int64_t num_no_potential_window_ = 0;
158};
159
160} // namespace sat
161} // namespace operations_research
162
163#endif // OR_TOOLS_SAT_CUMULATIVE_ENERGY_H_
Implementation of AddCumulativeOverloadCheckerDff().
CumulativeDualFeasibleEnergyConstraint(AffineExpression capacity, SchedulingConstraintHelper *helper, SchedulingDemandHelper *demands, Model *model)
Implementation of AddCumulativeOverloadChecker().
void RegisterWith(GenericLiteralWatcher *watcher)
CumulativeEnergyConstraint(AffineExpression capacity, SchedulingConstraintHelper *helper, SchedulingDemandHelper *demands, Model *model)
CumulativeIsAfterSubsetConstraint(IntegerVariable var, AffineExpression capacity, const std::vector< int > &subtasks, absl::Span< const IntegerValue > offsets, SchedulingConstraintHelper *helper, SchedulingDemandHelper *demands, Model *model)
Base class for CP like propagators.
Definition integer.h:1414
Simple class to add statistics by name and print them at the end.
IntVar * var
GRBmodel * model
void AddCumulativeOverloadCheckerDff(AffineExpression capacity, SchedulingConstraintHelper *helper, SchedulingDemandHelper *demands, Model *model)
void AddCumulativeOverloadChecker(AffineExpression capacity, SchedulingConstraintHelper *helper, SchedulingDemandHelper *demands, Model *model)
In SWIG mode, we don't want anything besides these top-level includes.