17 #include "absl/strings/str_format.h" 29 const char* kUnaryNames[] = {
30 "ENDS_AFTER",
"ENDS_AT",
"ENDS_BEFORE",
"STARTS_AFTER",
31 "STARTS_AT",
"STARTS_BEFORE",
"CROSS_DATE",
"AVOID_DATE",
34 const char* kBinaryNames[] = {
35 "ENDS_AFTER_END",
"ENDS_AFTER_START",
"ENDS_AT_END",
36 "ENDS_AT_START",
"STARTS_AFTER_END",
"STARTS_AFTER_START",
37 "STARTS_AT_END",
"STARTS_AT_START",
"STAYS_IN_SYNC"};
39 class IntervalUnaryRelation :
public Constraint {
41 IntervalUnaryRelation(Solver*
const s, IntervalVar*
const t, int64_t d,
43 : Constraint(s), t_(t), d_(d), rel_(rel) {}
44 ~IntervalUnaryRelation()
override {}
48 void InitialPropagate()
override;
50 std::string DebugString()
const override {
51 return absl::StrFormat(
"(%s %s %d)", t_->DebugString(), kUnaryNames[rel_],
55 void Accept(ModelVisitor*
const visitor)
const override {
64 IntervalVar*
const t_;
69 void IntervalUnaryRelation::Post() {
71 Demon* d = solver()->MakeConstraintInitialPropagateCallback(
this);
76 void IntervalUnaryRelation::InitialPropagate() {
117 return RevAlloc(
new IntervalUnaryRelation(
this, t, d, r));
123 class IntervalBinaryRelation :
public Constraint {
128 :
Constraint(s), t1_(t1), t2_(t2), rel_(rel), delay_(delay) {}
129 ~IntervalBinaryRelation()
override {}
131 void Post()
override;
133 void InitialPropagate()
override;
135 std::string DebugString()
const override {
136 return absl::StrFormat(
"(%s %s %s)", t1_->DebugString(), kBinaryNames[rel_],
140 void Accept(ModelVisitor*
const visitor)
const override {
149 IntervalVar*
const t1_;
150 IntervalVar*
const t2_;
152 const int64_t delay_;
155 void IntervalBinaryRelation::Post() {
157 Demon* d = solver()->MakeConstraintInitialPropagateCallback(
this);
164 void IntervalBinaryRelation::InitialPropagate() {
236 return RevAlloc(
new IntervalBinaryRelation(
this, t1, t2, r, 0));
242 return RevAlloc(
new IntervalBinaryRelation(
this, t1, t2, r, delay));
248 class TemporalDisjunction :
public Constraint {
250 enum State { ONE_BEFORE_TWO, TWO_BEFORE_ONE, UNDECIDED };
252 TemporalDisjunction(Solver*
const s, IntervalVar*
const t1,
253 IntervalVar*
const t2, IntVar*
const alt)
254 : Constraint(s), t1_(t1), t2_(t2), alt_(alt), state_(UNDECIDED) {}
255 ~TemporalDisjunction()
override {}
257 void Post()
override;
258 void InitialPropagate()
override;
259 std::string DebugString()
const override;
264 void Decide(State s);
267 void Accept(ModelVisitor*
const visitor)
const override {
277 IntervalVar*
const t1_;
278 IntervalVar*
const t2_;
283 void TemporalDisjunction::Post() {
284 Solver*
const s = solver();
291 if (alt_ !=
nullptr) {
298 void TemporalDisjunction::InitialPropagate() {
299 if (alt_ !=
nullptr) {
302 if (alt_ !=
nullptr && alt_->
Bound()) {
310 std::string TemporalDisjunction::DebugString()
const {
312 (out = absl::StrFormat(
"TemporalDisjunction(%s, %s", t1_->
DebugString(),
314 if (alt_ !=
nullptr) {
315 absl::StrAppendFormat(&out,
" => %s", alt_->
DebugString());
321 void TemporalDisjunction::TryToDecide() {
326 Decide(TWO_BEFORE_ONE);
328 Decide(ONE_BEFORE_TWO);
333 void TemporalDisjunction::RangeDemon1() {
335 case ONE_BEFORE_TWO: {
341 case TWO_BEFORE_ONE: {
353 void TemporalDisjunction::RangeDemon2() {
356 case ONE_BEFORE_TWO: {
362 case TWO_BEFORE_ONE: {
375 void TemporalDisjunction::RangeAlt() {
377 if (alt_->
Value() == 0) {
378 Decide(ONE_BEFORE_TWO);
380 Decide(TWO_BEFORE_ONE);
384 void TemporalDisjunction::Decide(State s) {
387 if (state_ != UNDECIDED && state_ != s) {
390 solver()->SaveValue(reinterpret_cast<int*>(&state_));
392 if (alt_ !=
nullptr) {
393 if (s == ONE_BEFORE_TWO) {
407 return RevAlloc(
new TemporalDisjunction(
this, t1, t2, alt));
412 return RevAlloc(
new TemporalDisjunction(
this, t1, t2,
nullptr));
t ends after d, i.e. End(t) >= d.
virtual int64_t Value() const =0
This method returns the value of the variable.
static const char kIntervalUnaryRelation[]
t1 ends at t2 end, i.e. End(t1) == End(t2) + delay.
BinaryIntervalRelation
This enum is used in Solver::MakeIntervalVarRelation to specify the temporal relation between the two...
t ends before d, i.e. End(t) <= d.
Constraint * MakeIntervalVarRelationWithDelay(IntervalVar *const t1, BinaryIntervalRelation r, IntervalVar *const t2, int64_t delay)
This method creates a relation between two interval vars.
A constraint is the main modeling object.
virtual void SetEndRange(int64_t mi, int64_t ma)=0
t1 ends at t2 start, i.e. End(t1) == Start(t2) + delay.
void WhenAnything(Demon *const d)
Attaches a demon awakened when anything about this interval changes.
t ends at d, i.e. End(t) == d.
virtual void SetStartMin(int64_t m)=0
t1 starts at t2 start, i.e. Start(t1) == Start(t2) + delay.
static const char kRelationArgument[]
t starts at d, i.e. Start(t) == d.
virtual bool Bound() const
Returns true if the min and the max of the expression are equal.
Interval variables are often used in scheduling.
t1 ends after t2 end, i.e. End(t1) >= End(t2) + delay.
virtual int64_t StartMax() const =0
Constraint * MakeTemporalDisjunction(IntervalVar *const t1, IntervalVar *const t2, IntVar *const alt)
This constraint implements a temporal disjunction between two interval vars t1 and t2.
Demon * MakeConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)
virtual bool MayBePerformed() const =0
virtual int64_t EndMax() const =0
#define DCHECK_NE(val1, val2)
UnaryIntervalRelation
This enum is used in Solver::MakeIntervalVarRelation to specify the temporal relation between an inte...
t1 starts at t2 end, i.e. Start(t1) == End(t2) + delay.
t1 starts after t2 end, i.e. Start(t1) >= End(t2) + delay.
Constraint * MakeIntervalVarRelation(IntervalVar *const t, UnaryIntervalRelation r, int64_t d)
This method creates a relation between an interval var and a date.
The class IntVar is a subset of IntExpr.
t1 ends after t2 start, i.e. End(t1) >= Start(t2) + delay.
static const char kIntervalBinaryRelation[]
STARTS_AT_START and ENDS_AT_END at the same time.
STARTS_BEFORE and ENDS_AFTER at the same time, i.e.
static const char kIntervalDisjunction[]
virtual void SetValue(int64_t v)
This method sets the value of the expression.
std::string DebugString() const override
T * RevAlloc(T *object)
Registers the given object as being reversible.
virtual int64_t EndMin() const =0
These methods query, set, and watch the end position of the interval var.
#define DCHECK(condition)
STARTS_AFTER or ENDS_BEFORE, i.e.
virtual void SetEndMin(int64_t m)=0
static const char kLeftArgument[]
#define DCHECK_EQ(val1, val2)
virtual void SetStartMax(int64_t m)=0
Collection of objects used to extend the Constraint Solver library.
virtual void SetStartRange(int64_t mi, int64_t ma)=0
static const char kValueArgument[]
virtual void WhenRange(Demon *d)=0
Attach a demon that will watch the min or the max of the expression.
t starts before d, i.e. Start(t) <= d.
virtual bool MustBePerformed() const =0
These methods query, set, and watch the performed status of the interval var.
static const char kTargetArgument[]
virtual void SetEndMax(int64_t m)=0
t1 starts after t2 start, i.e. Start(t1) >= Start(t2) + delay.
virtual void SetRange(int64_t l, int64_t u)
This method sets both the min and the max of the expression.
static const char kRightArgument[]
static const char kIntervalArgument[]
t starts after d, i.e. Start(t) >= d.
virtual int64_t StartMin() const =0
These methods query, set, and watch the start position of the interval var.