00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <stddef.h>
00017 #include <string>
00018
00019 #include "base/logging.h"
00020 #include "constraint_solver/constraint_solver.h"
00021
00022 namespace operations_research {
00023
00024
00025
00026
00027 namespace {
00028 class RangeEquality : public Constraint {
00029 public:
00030 RangeEquality(Solver* const s, IntVar* const l, IntVar* const r);
00031 virtual ~RangeEquality() {}
00032 virtual void Post();
00033 virtual void InitialPropagate();
00034 virtual string DebugString() const;
00035 virtual IntVar* Var() {
00036 return solver()->MakeIsEqualVar(left_, right_);
00037 }
00038 virtual void Accept(ModelVisitor* const visitor) const {
00039 visitor->BeginVisitConstraint(ModelVisitor::kEquality, this);
00040 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
00041 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
00042 right_);
00043 visitor->EndVisitConstraint(ModelVisitor::kEquality, this);
00044 }
00045
00046 private:
00047 IntVar* const left_;
00048 IntVar* const right_;
00049 };
00050
00051 RangeEquality::RangeEquality(Solver* const s, IntVar* const l, IntVar* const r)
00052 : Constraint(s), left_(l), right_(r) {}
00053
00054 void RangeEquality::Post() {
00055 Demon* d = solver()->MakeConstraintInitialPropagateCallback(this);
00056 left_->WhenRange(d);
00057 right_->WhenRange(d);
00058 }
00059
00060 void RangeEquality::InitialPropagate() {
00061 left_->SetRange(right_->Min(), right_->Max());
00062 right_->SetRange(left_->Min(), left_->Max());
00063 }
00064
00065 string RangeEquality::DebugString() const {
00066 return left_->DebugString() + " == " + right_->DebugString();
00067 }
00068 }
00069
00070 Constraint* Solver::MakeEquality(IntVar* const l, IntVar* const r) {
00071 CHECK(l != NULL) << "left expression NULL, maybe a bad cast";
00072 CHECK(r != NULL) << "left expression NULL, maybe a bad cast";
00073 CHECK_EQ(this, l->solver());
00074 CHECK_EQ(this, r->solver());
00075 return RevAlloc(new RangeEquality(this, l, r));
00076 }
00077
00078
00079
00080
00081 namespace {
00082 class RangeLessOrEqual : public Constraint {
00083 public:
00084 RangeLessOrEqual(Solver* const s, IntVar* const l, IntVar* const r);
00085 virtual ~RangeLessOrEqual() {}
00086 virtual void Post();
00087 virtual void InitialPropagate();
00088 virtual string DebugString() const;
00089 virtual IntVar* Var() {
00090 return solver()->MakeIsLessOrEqualVar(left_, right_);
00091 }
00092 virtual void Accept(ModelVisitor* const visitor) const {
00093 visitor->BeginVisitConstraint(ModelVisitor::kLessOrEqual, this);
00094 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
00095 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
00096 right_);
00097 visitor->EndVisitConstraint(ModelVisitor::kLessOrEqual, this);
00098 }
00099
00100 private:
00101 IntVar* const left_;
00102 IntVar* const right_;
00103 };
00104
00105 RangeLessOrEqual::RangeLessOrEqual(Solver* const s, IntVar* const l,
00106 IntVar* const r)
00107 : Constraint(s), left_(l), right_(r) {}
00108
00109 void RangeLessOrEqual::Post() {
00110 Demon* d = solver()->MakeConstraintInitialPropagateCallback(this);
00111 left_->WhenRange(d);
00112 right_->WhenRange(d);
00113 }
00114
00115 void RangeLessOrEqual::InitialPropagate() {
00116 left_->SetMax(right_->Max());
00117 right_->SetMin(left_->Min());
00118 }
00119
00120 string RangeLessOrEqual::DebugString() const {
00121 return left_->DebugString() + " <= " + right_->DebugString();
00122 }
00123 }
00124
00125 Constraint* Solver::MakeLessOrEqual(IntVar* const l, IntVar* const r) {
00126 CHECK(l != NULL) << "left expression NULL, maybe a bad cast";
00127 CHECK(r != NULL) << "left expression NULL, maybe a bad cast";
00128 CHECK_EQ(this, l->solver());
00129 CHECK_EQ(this, r->solver());
00130 return RevAlloc(new RangeLessOrEqual(this, l, r));
00131 }
00132
00133
00134
00135
00136 namespace {
00137 class RangeGreaterOrEqual : public Constraint {
00138 public:
00139 RangeGreaterOrEqual(Solver* const s, IntVar* const l, IntVar* const r);
00140 virtual ~RangeGreaterOrEqual() {}
00141 virtual void Post();
00142 virtual void InitialPropagate();
00143 virtual string DebugString() const;
00144 virtual IntVar* Var() {
00145 return solver()->MakeIsGreaterOrEqualVar(left_, right_);
00146 }
00147 virtual void Accept(ModelVisitor* const visitor) const {
00148 visitor->BeginVisitConstraint(ModelVisitor::kGreaterOrEqual, this);
00149 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
00150 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
00151 right_);
00152 visitor->EndVisitConstraint(ModelVisitor::kGreaterOrEqual, this);
00153 }
00154
00155 private:
00156 IntVar* const left_;
00157 IntVar* const right_;
00158 };
00159
00160 RangeGreaterOrEqual::RangeGreaterOrEqual(Solver* const s, IntVar* const l,
00161 IntVar* const r)
00162 : Constraint(s), left_(l), right_(r) {}
00163
00164 void RangeGreaterOrEqual::Post() {
00165 Demon* d = solver()->MakeConstraintInitialPropagateCallback(this);
00166 left_->WhenRange(d);
00167 right_->WhenRange(d);
00168 }
00169
00170 void RangeGreaterOrEqual::InitialPropagate() {
00171 left_->SetMin(right_->Min());
00172 right_->SetMax(left_->Max());
00173 }
00174
00175 string RangeGreaterOrEqual::DebugString() const {
00176 return left_->DebugString() + " >= " + right_->DebugString();
00177 }
00178 }
00179
00180 Constraint* Solver::MakeGreaterOrEqual(IntVar* const l, IntVar* const r) {
00181 CHECK(l != NULL) << "left expression NULL, maybe a bad cast";
00182 CHECK(r != NULL) << "left expression NULL, maybe a bad cast";
00183 CHECK_EQ(this, l->solver());
00184 CHECK_EQ(this, r->solver());
00185 return RevAlloc(new RangeGreaterOrEqual(this, l, r));
00186 }
00187
00188
00189
00190
00191 namespace {
00192 class RangeLess : public Constraint {
00193 public:
00194 RangeLess(Solver* const s, IntVar* const l, IntVar* const r);
00195 virtual ~RangeLess() {}
00196 virtual void Post();
00197 virtual void InitialPropagate();
00198 virtual string DebugString() const;
00199 virtual IntVar* Var() {
00200 return solver()->MakeIsLessVar(left_, right_);
00201 }
00202 virtual void Accept(ModelVisitor* const visitor) const {
00203 visitor->BeginVisitConstraint(ModelVisitor::kLess, this);
00204 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
00205 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
00206 right_);
00207 visitor->EndVisitConstraint(ModelVisitor::kLess, this);
00208 }
00209
00210 private:
00211 IntVar* const left_;
00212 IntVar* const right_;
00213 };
00214
00215 RangeLess::RangeLess(Solver* const s, IntVar* const l, IntVar* const r)
00216 : Constraint(s), left_(l), right_(r) {}
00217
00218 void RangeLess::Post() {
00219 Demon* d = solver()->MakeConstraintInitialPropagateCallback(this);
00220 left_->WhenRange(d);
00221 right_->WhenRange(d);
00222 }
00223
00224 void RangeLess::InitialPropagate() {
00225 left_->SetMax(right_->Max() - 1);
00226 right_->SetMin(left_->Min() + 1);
00227 }
00228
00229 string RangeLess::DebugString() const {
00230 return left_->DebugString() + " < " + right_->DebugString();
00231 }
00232 }
00233
00234 Constraint* Solver::MakeLess(IntVar* const l, IntVar* const r) {
00235 CHECK(l != NULL) << "left expression NULL, maybe a bad cast";
00236 CHECK(r != NULL) << "left expression NULL, maybe a bad cast";
00237 CHECK_EQ(this, l->solver());
00238 CHECK_EQ(this, r->solver());
00239 return RevAlloc(new RangeLess(this, l, r));
00240 }
00241
00242
00243
00244
00245 namespace {
00246 class RangeGreater : public Constraint {
00247 public:
00248 RangeGreater(Solver* const s, IntVar* const l, IntVar* const r);
00249 virtual ~RangeGreater() {}
00250 virtual void Post();
00251 virtual void InitialPropagate();
00252 virtual string DebugString() const;
00253 virtual IntVar* Var() {
00254 return solver()->MakeIsGreaterVar(left_, right_);
00255 }
00256 virtual void Accept(ModelVisitor* const visitor) const {
00257 visitor->BeginVisitConstraint(ModelVisitor::kGreater, this);
00258 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
00259 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
00260 right_);
00261 visitor->EndVisitConstraint(ModelVisitor::kGreater, this);
00262 }
00263
00264 private:
00265 IntVar* const left_;
00266 IntVar* const right_;
00267 };
00268
00269 RangeGreater::RangeGreater(Solver* const s, IntVar* const l, IntVar* const r)
00270 : Constraint(s), left_(l), right_(r) {}
00271
00272 void RangeGreater::Post() {
00273 Demon* d = solver()->MakeConstraintInitialPropagateCallback(this);
00274 left_->WhenRange(d);
00275 right_->WhenRange(d);
00276 }
00277
00278 void RangeGreater::InitialPropagate() {
00279 left_->SetMin(right_->Min() + 1);
00280 right_->SetMax(left_->Max() - 1);
00281 }
00282
00283 string RangeGreater::DebugString() const {
00284 return left_->DebugString() + " > " + right_->DebugString();
00285 }
00286 }
00287
00288 Constraint* Solver::MakeGreater(IntVar* const l, IntVar* const r) {
00289 CHECK(l != NULL) << "left expression NULL, maybe a bad cast";
00290 CHECK(r != NULL) << "left expression NULL, maybe a bad cast";
00291 CHECK_EQ(this, l->solver());
00292 CHECK_EQ(this, r->solver());
00293 return RevAlloc(new RangeGreater(this, l, r));
00294 }
00295
00296
00297
00298
00299 namespace {
00300 class DiffVar : public Constraint {
00301 public:
00302 DiffVar(Solver* const s, IntVar* const l, IntVar* const r);
00303 virtual ~DiffVar() {}
00304 virtual void Post();
00305 virtual void InitialPropagate();
00306 virtual string DebugString() const;
00307 virtual IntVar* Var() {
00308 return solver()->MakeIsDifferentVar(left_, right_);
00309 }
00310
00311 virtual void Accept(ModelVisitor* const visitor) const {
00312 visitor->BeginVisitConstraint(ModelVisitor::kNonEqual, this);
00313 visitor->VisitIntegerExpressionArgument(ModelVisitor::kLeftArgument, left_);
00314 visitor->VisitIntegerExpressionArgument(ModelVisitor::kRightArgument,
00315 right_);
00316 visitor->EndVisitConstraint(ModelVisitor::kNonEqual, this);
00317 }
00318
00319 private:
00320 IntVar* const left_;
00321 IntVar* const right_;
00322 };
00323
00324 DiffVar::DiffVar(Solver* const s, IntVar* const l, IntVar* const r)
00325 : Constraint(s), left_(l), right_(r) {}
00326
00327 void DiffVar::Post() {
00328 Demon* d = solver()->MakeConstraintInitialPropagateCallback(this);
00329 left_->WhenBound(d);
00330 right_->WhenBound(d);
00331
00332 }
00333
00334 void DiffVar::InitialPropagate() {
00335 if (left_->Bound()) {
00336 right_->RemoveValue(left_->Min());
00337
00338
00339 }
00340 if (right_->Bound()) {
00341 left_->RemoveValue(right_->Min());
00342 }
00343 }
00344
00345 string DiffVar::DebugString() const {
00346 return left_->DebugString() + " != " + right_->DebugString();
00347 }
00348 }
00349
00350 Constraint* Solver::MakeNonEquality(IntVar* const l, IntVar* const r) {
00351 CHECK(l != NULL) << "left expression NULL, maybe a bad cast";
00352 CHECK(r != NULL) << "left expression NULL, maybe a bad cast";
00353 CHECK_EQ(this, l->solver());
00354 CHECK_EQ(this, r->solver());
00355 return RevAlloc(new DiffVar(this, l, r));
00356 }
00357
00358 }