Google OR-Tools: ortools/constraint_solver/timetabling.cc Source File
18#include "absl/strings/str_format.h"
27const char* kUnaryNames[] = {
28 "ENDS_AFTER", "ENDS_AT", "ENDS_BEFORE", "STARTS_AFTER",
29 "STARTS_AT", "STARTS_BEFORE", "CROSS_DATE", "AVOID_DATE",
32const char* kBinaryNames[] = {
33 "ENDS_AFTER_END", "ENDS_AFTER_START", "ENDS_AT_END",
34 "ENDS_AT_START", "STARTS_AFTER_END", "STARTS_AFTER_START",
35 "STARTS_AT_END", "STARTS_AT_START", "STAYS_IN_SYNC"};
37class IntervalUnaryRelation : public Constraint {
39 IntervalUnaryRelation(Solver* const s, IntervalVar* const t, int64_t d,
41 : Constraint(s), t_(t), d_(d), rel_(rel) {}
42 ~IntervalUnaryRelation() override {}
46 void InitialPropagate() override;
48 std::string DebugString() const override {
49 return absl::StrFormat("(%s %s %d)", t_->DebugString(), kUnaryNames[rel_],
53 void Accept(ModelVisitor* const visitor) const override {
67void IntervalUnaryRelation::Post() {
69 Demon* d = solver()->MakeConstraintInitialPropagateCallback(this);
74void IntervalUnaryRelation::InitialPropagate() {
93 case Solver::STARTS_BEFORE:
101 if (t_->EndMin() > d_) {
103 } else if (t_->StartMax() < d_) {
121class IntervalBinaryRelation : public Constraint {
126 : Constraint(s), t1_(t1), t2_(t2), rel_(rel), delay_(delay) {}
127 ~IntervalBinaryRelation() override {}
131 void InitialPropagate() override;
133 std::string DebugString() const override {
134 return absl::StrFormat("(%s %s %s)", t1_->DebugString(), kBinaryNames[rel_],
138 void Accept(ModelVisitor* const visitor) const override {
139 visitor->BeginVisitConstraint(ModelVisitor::kIntervalBinaryRelation, this);
140 visitor->VisitIntervalArgument(ModelVisitor::kLeftArgument, t1_);
141 visitor->VisitIntegerArgument(ModelVisitor::kRelationArgument, rel_);
142 visitor->VisitIntervalArgument(ModelVisitor::kRightArgument, t2_);
143 visitor->EndVisitConstraint(ModelVisitor::kIntervalBinaryRelation, this);
149 const Solver::BinaryIntervalRelation rel_;
153void IntervalBinaryRelation::Post() {
155 Demon* d = solver()->MakeConstraintInitialPropagateCallback(this);
162void IntervalBinaryRelation::InitialPropagate() {
165 case Solver::ENDS_AFTER_END:
168 case Solver::ENDS_AFTER_START:
174 case Solver::ENDS_AT_START:
177 case Solver::STARTS_AFTER_END:
180 case Solver::STARTS_AFTER_START:
183 case Solver::STARTS_AT_END:
186 case Solver::STARTS_AT_START:
189 case Solver::STAYS_IN_SYNC:
198 case Solver::ENDS_AFTER_END:
201 case Solver::ENDS_AFTER_START:
207 case Solver::ENDS_AT_START:
210 case Solver::STARTS_AFTER_END:
213 case Solver::STARTS_AFTER_START:
216 case Solver::STARTS_AT_END:
219 case Solver::STARTS_AT_START:
222 case Solver::STAYS_IN_SYNC:
234 return RevAlloc(new IntervalBinaryRelation(this, t1, t2, r, 0));
240 return RevAlloc(new IntervalBinaryRelation(this, t1, t2, r, delay));
246class TemporalDisjunction : public Constraint {
248 enum State { ONE_BEFORE_TWO, TWO_BEFORE_ONE, UNDECIDED };
250 TemporalDisjunction(Solver* const s, IntervalVar* const t1,
251 IntervalVar* const t2, IntVar* const alt)
252 : Constraint(s), t1_(t1), t2_(t2), alt_(alt), state_(UNDECIDED) {}
253 ~TemporalDisjunction() override {}
256 void InitialPropagate() override;
257 std::string DebugString() const override;
265 void Accept(ModelVisitor* const visitor) const override {
266 visitor->BeginVisitConstraint(ModelVisitor::kIntervalDisjunction, this);
267 visitor->VisitIntervalArgument(ModelVisitor::kLeftArgument, t1_);
268 visitor->VisitIntervalArgument(ModelVisitor::kRightArgument, t2_);
269 visitor->VisitIntegerExpressionArgument(ModelVisitor::kTargetArgument,
271 visitor->EndVisitConstraint(ModelVisitor::kIntervalDisjunction, this);
281void TemporalDisjunction::Post() {
282 Solver* const s = solver();
296void TemporalDisjunction::InitialPropagate() {
300 if (alt_ != nullptr && alt_->Bound()) {
308std::string TemporalDisjunction::DebugString() const {
310 (out = absl::StrFormat("TemporalDisjunction(%s, %s", t1_->DebugString(),
313 absl::StrAppendFormat(&out, " => %s", alt_->DebugString());
319void TemporalDisjunction::TryToDecide() {
320 DCHECK_EQ(UNDECIDED, state_);
331void TemporalDisjunction::RangeDemon1() {
351void TemporalDisjunction::RangeDemon2() {
373void TemporalDisjunction::RangeAlt() {
375 if (alt_->Value() == 0) {
382void TemporalDisjunction::Decide(State s) {
385 if (state_ != UNDECIDED && state_ != s) {
388 solver()->SaveValue(reinterpret_cast<int*>(&state_));
391 if (s == ONE_BEFORE_TWO) {
405 return RevAlloc(new TemporalDisjunction(this, t1, t2, alt));
410 return RevAlloc(new TemporalDisjunction(this, t1, t2, nullptr));
virtual void SetValue(int64_t v)
This method sets the value of the expression.
virtual bool Bound() const
Returns true if the min and the max of the expression are equal.
virtual void SetRange(int64_t l, int64_t u)
This method sets both the min and the max of the expression.
virtual void WhenRange(Demon *d)=0
Attach a demon that will watch the min or the max of the expression.
virtual int64_t Value() const =0
virtual void SetEndRange(int64_t mi, int64_t ma)=0
virtual int64_t EndMax() const =0
virtual int64_t EndMin() const =0
These methods query, set, and watch the end position of the interval var.
virtual void SetEndMax(int64_t m)=0
virtual void SetStartRange(int64_t mi, int64_t ma)=0
virtual void SetStartMax(int64_t m)=0
void WhenAnything(Demon *d)
Attaches a demon awakened when anything about this interval changes.
virtual int64_t StartMax() const =0
virtual bool MayBePerformed() const =0
virtual void SetEndMin(int64_t m)=0
virtual void SetStartMin(int64_t m)=0
virtual int64_t StartMin() const =0
virtual bool MustBePerformed() const =0
static const char kRelationArgument[]
static const char kIntervalUnaryRelation[]
static const char kValueArgument[]
static const char kIntervalArgument[]
std::string DebugString() const override
Constraint * MakeTemporalDisjunction(IntervalVar *t1, IntervalVar *t2, IntVar *alt)
Definition timetabling.cc:402
Constraint * MakeIntervalVarRelationWithDelay(IntervalVar *t1, BinaryIntervalRelation r, IntervalVar *t2, int64_t delay)
Definition timetabling.cc:237
Constraint * MakeIntervalVarRelation(IntervalVar *t, UnaryIntervalRelation r, int64_t d)
Definition timetabling.cc:112
Demon * MakeConstraintDemon0(Solver *const s, T *const ct, void(T::*method)(), const std::string &name)