00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <gecode/driver.hh>
00039 #include <gecode/int.hh>
00040 #include <gecode/minimodel.hh>
00041
00042 #include <iomanip>
00043
00044 using namespace Gecode;
00045
00046
00047 namespace {
00048
00049 extern const int* problems[];
00050
00051 extern const unsigned int n_problems;
00052 }
00053
00054 namespace {
00060 class CarOptions : public SizeOptions {
00061 private:
00063 Driver::UnsignedIntOption _maxstall;
00064
00065 public:
00067 CarOptions(const char* s)
00068 : SizeOptions(s),
00069 _maxstall("-maxstall", "Maximum numbere of stalls", 30)
00070 {
00071
00072 add(_maxstall);
00073 }
00075 void parse(int& argc, char* argv[]) {
00076 SizeOptions::parse(argc,argv);
00077 }
00079 int maxstall(void) const { return _maxstall.value(); }
00080 };
00081
00082
00100 template <class View>
00101 class PushToEnd : public NaryOnePropagator<View,Int::PC_INT_BND> {
00102 protected:
00103 using NaryOnePropagator<View,Int::PC_INT_BND>::x;
00104 using NaryOnePropagator<View,Int::PC_INT_BND>::y;
00105 int val;
00106
00108 PushToEnd(Space& home, bool share, PushToEnd& p);
00110 PushToEnd(Space& home, ViewArray<View>& x0, View y0, int val0);
00111 public:
00113 PushToEnd(Space& home, bool share, Propagator& p,
00114 ViewArray<View>& x0, View y0, int val0);
00116 virtual Actor* copy(Space& home, bool share);
00118 virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
00120 static ExecStatus post(Space& home,
00121 ViewArray<View>& x0, View y0, int val0);
00122 };
00123
00124 template <class View>
00125 inline
00126 PushToEnd<View>::PushToEnd(Space& home,
00127 ViewArray<View>& x0, View y0, int val0)
00128 : NaryOnePropagator<View,Int::PC_INT_BND>(home,x0,y0), val(val0) {}
00129
00130 template <class View>
00131 ExecStatus
00132 PushToEnd<View>::post(Space& home,
00133 ViewArray<View>& x0, View y0, int val0) {
00134 (void) new (home) PushToEnd<View>(home,x0,y0,val0);
00135 return ES_OK;
00136 }
00137
00138 template <class View>
00139 inline
00140 PushToEnd<View>::PushToEnd(Space& home, bool share, PushToEnd<View>& p)
00141 : NaryOnePropagator<View,Int::PC_INT_BND>(home,share,p), val(p.val) {}
00142
00143 template <class View>
00144 inline
00145 PushToEnd<View>::PushToEnd(Space& home, bool share, Propagator& p,
00146 ViewArray<View>& x0, View y0, int val0)
00147 : NaryOnePropagator<View,Int::PC_INT_BND>(home,share,p,x0,y0), val(val0) {}
00148
00149 template <class View>
00150 Actor*
00151 PushToEnd<View>::copy(Space& home, bool share) {
00152 return new (home) PushToEnd<View>(home,share,*this);
00153 }
00154
00155 template <class View>
00156 ExecStatus
00157 PushToEnd<View>::propagate(Space& home, const ModEventDelta&) {
00158
00159 int min = 0;
00160 for (int i = x.size(); i-- && x[i].min() >= val-1; ) {
00161 ++min;
00162 }
00163
00164 int max = 0;
00165 {
00166 int i = x.size();
00167 while (i--) {
00168 if (x[i].max() != val) break;
00169 ++max;
00170 if (max >= y.max()) break;
00171 }
00172
00173 while (i--) {
00174 GECODE_ME_CHECK(x[i].le(home, val));
00175 }
00176 }
00177
00178
00179 GECODE_ME_CHECK(y.gq(home, min));
00180 GECODE_ME_CHECK(y.lq(home, max));
00181
00182
00183 for (int i = 0, pos = x.size()-1; i < y.min(); ++i, --pos) {
00184 GECODE_ME_CHECK(x[pos].eq(home, val));
00185 }
00186
00187 return y.assigned() ? home.ES_SUBSUMED(*this) : ES_FIX;
00188 }
00189
00192 void pushtoend(Space& home, IntVarArgs x, IntVar y, int val) {
00193 ViewArray<Int::IntView> vx(home, x);
00194 Int::IntView vy(y);
00195 GECODE_ES_FAIL(PushToEnd<Int::IntView>::post(home, vx, vy, val));
00196 }
00197
00198 }
00199
00200
00212 class CarSequencing : public Script {
00213 public:
00215 enum {
00216 SEARCH_BAB,
00217 SEARCH_RESTART
00218 };
00220 enum {
00221 BRANCH_INORDER,
00222 BRANCH_MIDDLE
00223 };
00225 enum {
00226 PROP_REGULAR,
00227 PROP_CUSTOM
00228 };
00229 protected:
00231 const int problem;
00233 const int ncars;
00235 const int noptions;
00237 const int nclasses;
00239 const int maxstall;
00241 const int stallval;
00243 const int endval;
00245 IntVar nstall;
00247 IntVar nend;
00249 IntVarArray s;
00250 public:
00252 CarSequencing(const CarOptions& opt)
00253 : problem(opt.size()),
00254 ncars(problems[problem][0]),
00255 noptions(problems[problem][1]),
00256 nclasses(problems[problem][2]),
00257 maxstall(opt.maxstall()),
00258 stallval(nclasses),
00259 endval(nclasses+1),
00260 nstall(*this, 0, maxstall),
00261 nend(*this, 0, maxstall),
00262 s(*this, ncars+maxstall, 0, nclasses+1)
00263 {
00264
00265 const int* probit = problems[problem] + 3;
00266
00267
00268 IntArgs max(noptions), block(noptions);
00269 for (int i = 0; i < noptions; ++i ) {
00270 max[i] = *probit++;
00271 }
00272 for (int i = 0; i < noptions; ++i ) {
00273 block[i] = *probit++;
00274 }
00275
00276 IntArgs ncc(nclasses);
00277
00278 IntSetArgs classes(noptions);
00279 int** cdata = new int*[noptions];
00280 for (int i = noptions; i--; ) cdata[i] = new int[nclasses];
00281 int* n = new int[noptions];
00282 for (int i = noptions; i--; ) n[i] = 0;
00283
00284 for (int c = 0; c < nclasses; ++c) {
00285 *probit++;
00286 ncc[c] = *probit++;
00287 for (int o = 0; o < noptions; ++o) {
00288 if (*probit++) {
00289 cdata[o][n[o]++] = c;
00290 }
00291 }
00292 }
00293
00294 for (int o = noptions; o--; ) {
00295 classes[o] = IntSet(cdata[o], n[o]);
00296 delete [] cdata[o];
00297 }
00298 delete [] cdata;
00299 delete [] n;
00300
00301
00302 {
00303 IntSetArgs c(nclasses+2);
00304 for (int i = nclasses; i--; ) {
00305 c[i] = IntSet(ncc[i], ncc[i]);
00306 }
00307 c[stallval] = IntSet(0, maxstall);
00308 c[ endval] = IntSet(0, maxstall);
00309 count(*this, s, c);
00310 }
00311
00312
00313 count(*this, s, stallval, IRT_EQ, nstall);
00314 count(*this, s, endval, IRT_EQ, nend);
00315 rel(*this, nstall+nend == maxstall);
00316
00317
00318 IntSet one(1, 1);
00319 for (int o = noptions; o--; ) {
00320
00321 BoolVarArgs sb(s.size());
00322 for (int i = s.size(); i--; ) {
00323 BoolVar b(*this, 0, 1);
00324 dom(*this, s[i], classes[o], b);
00325 sb[i] = b;
00326 }
00327 sequence(*this, sb, one, block[o], 0, max[o]);
00328 }
00329
00330
00331 switch (opt.propagation()) {
00332 case PROP_REGULAR: {
00333 IntArgs notend(nclasses), notstallend(nclasses+1);
00334 for (int i = nclasses; i--; ) {
00335 notend[i] = i;
00336 notstallend[i] = i;
00337 }
00338 notstallend[nclasses] = stallval;
00339 REG r = *REG(notend) + REG(notstallend) + *REG(endval);
00340 extensional(*this, s, r);
00341 for (int pos = s.size()-1, i = 0; i < maxstall; ++i, --pos) {
00342 rel(*this, (nend > i) >> (s[pos]==endval));
00343 }
00344 } break;
00345 case PROP_CUSTOM: {
00346 pushtoend(*this, s, nend, endval);
00347 } break;
00348 }
00349
00350
00351
00352 switch (opt.branching()) {
00353 case BRANCH_INORDER:
00354 branch(*this, s, INT_VAR_NONE, INT_VAL_MIN);
00355 break;
00356 case BRANCH_MIDDLE: {
00357 IntVarArgs m(s.size());
00358 int mid = s.size() / 2;
00359 int pos = 0;
00360 m[pos++] = s[mid];
00361 for (int i = 1; i <= m.size()/2; ++i) {
00362 if (mid-i >= 0)
00363 m[pos++] = s[mid-i];
00364 if (mid+i < s.size())
00365 m[pos++] = s[mid+i];
00366 }
00367 assert(pos == m.size());
00368 branch(*this, m, INT_VAR_NONE, INT_VAL_MIN);
00369 break;
00370 }
00371 }
00372 }
00373
00375 virtual void constrain(const Space& _best) {
00376 const CarSequencing& best = static_cast<const CarSequencing&>(_best);
00377 rel(*this, nstall, IRT_LE, best.nstall.val());
00378 }
00379
00381 virtual void
00382 print(std::ostream& os) const {
00383 int width = nclasses > 9 ? 2 : 1;
00384 const char* space = nclasses > 9 ? " " : "";
00385 os << "Stall slots=" << nstall
00386 << ", End slots=" << nend << std::endl;
00387 int i = 0;
00388 for (; i < s.size(); ++i) {
00389 if (s[i].assigned()) {
00390 int v = s[i].val();
00391 if (v == endval) break;
00392 if (v == stallval) os << space << "_ ";
00393 else os << std::setw(width) << v << " ";
00394 } else {
00395 os << space << "? ";
00396 }
00397 if ((i+1)%20 == 0) os << std::endl;
00398 }
00399 if (i%20)
00400 os << std::endl;
00401 os << std::endl;
00402 }
00403
00405 CarSequencing(bool share, CarSequencing& cs)
00406 : Script(share,cs),
00407 problem(cs.problem),
00408 ncars(cs.ncars),
00409 noptions(cs.noptions),
00410 nclasses(cs.nclasses),
00411 maxstall(cs.maxstall),
00412 stallval(cs.stallval),
00413 endval(cs.endval)
00414 {
00415 nstall.update(*this, share, cs.nstall);
00416 nend.update(*this, share, cs.nend);
00417 s.update(*this, share, cs.s);
00418 }
00420 virtual Space*
00421 copy(bool share) {
00422 return new CarSequencing(share,*this);
00423 }
00424 };
00425
00429 int
00430 main(int argc, char* argv[]) {
00431 CarOptions opt("CarSequencing");
00432 opt.solutions(0);
00433 opt.size(0);
00434 opt.search(CarSequencing::SEARCH_BAB);
00435 opt.search(CarSequencing::SEARCH_BAB, "bab");
00436 opt.search(CarSequencing::SEARCH_RESTART, "restart");
00437 opt.branching(CarSequencing::BRANCH_INORDER);
00438 opt.branching(CarSequencing::BRANCH_INORDER, "inorder");
00439 opt.branching(CarSequencing::BRANCH_MIDDLE, "middle");
00440 opt.propagation(CarSequencing::PROP_CUSTOM);
00441 opt.propagation(CarSequencing::PROP_REGULAR, "regular");
00442 opt.propagation(CarSequencing::PROP_CUSTOM, "custom");
00443 opt.parse(argc,argv);
00444 if (opt.size() >= n_problems) {
00445 std::cerr << "Error: size must be between 0 and "
00446 << n_problems-1 << std::endl;
00447 return 1;
00448 }
00449
00450 switch (opt.search()) {
00451 case CarSequencing::SEARCH_BAB:
00452 Script::run<CarSequencing,BAB,CarOptions>(opt); break;
00453 case CarSequencing::SEARCH_RESTART:
00454 Script::run<CarSequencing,Restart,CarOptions>(opt); break;
00455 }
00456 return 0;
00457 }
00458
00459
00460 namespace {
00462
00464 const int p0[] = {
00465 10, 5, 6,
00466 1, 2, 1, 2, 1,
00467 2, 3, 3, 5, 5,
00468 0, 1, 1, 0, 1, 1, 0,
00469 1, 1, 0, 0, 0, 1, 0,
00470 2, 2, 0, 1, 0, 0, 1,
00471 3, 2, 0, 1, 0, 1, 0,
00472 4, 2, 1, 0, 1, 0, 0,
00473 5, 2, 1, 1, 0, 0, 0
00474 };
00475
00476
00477
00478
00479 const int p1[] = {
00480 100, 5, 22,
00481 1, 2, 1, 2, 1,
00482 2, 3, 3, 5, 5,
00483 0, 6, 1, 0, 0, 1, 0,
00484 1, 10, 1, 1, 1, 0, 0,
00485 2, 2, 1, 1, 0, 0, 1,
00486 3, 2, 0, 1, 1, 0, 0,
00487 4, 8, 0, 0, 0, 1, 0,
00488 5, 15, 0, 1, 0, 0, 0,
00489 6, 1, 0, 1, 1, 1, 0,
00490 7, 5, 0, 0, 1, 1, 0,
00491 8, 2, 1, 0, 1, 1, 0,
00492 9, 3, 0, 0, 1, 0, 0,
00493 10, 2, 1, 0, 1, 0, 0,
00494 11, 1, 1, 1, 1, 0, 1,
00495 12, 8, 0, 1, 0, 1, 0,
00496 13, 3, 1, 0, 0, 1, 1,
00497 14, 10, 1, 0, 0, 0, 0,
00498 15, 4, 0, 1, 0, 0, 1,
00499 16, 4, 0, 0, 0, 0, 1,
00500 17, 2, 1, 0, 0, 0, 1,
00501 18, 4, 1, 1, 0, 0, 0,
00502 19, 6, 1, 1, 0, 1, 0,
00503 20, 1, 1, 0, 1, 0, 1,
00504 21, 1, 1, 1, 1, 1, 1,
00505 };
00506
00507
00508
00509
00510 const int p2[] = {
00511 100, 5, 22,
00512 1, 2, 1, 2, 1,
00513 2, 3, 3, 5, 5,
00514 0, 13, 1, 0, 0, 0, 0,
00515 1, 8, 0, 0, 0, 1, 0,
00516 2, 7, 0, 1, 0, 0, 0,
00517 3, 1, 1, 0, 0, 1, 0,
00518 4, 12, 0, 0, 1, 0, 0,
00519 5, 5, 0, 1, 0, 1, 0,
00520 6, 5, 0, 0, 1, 1, 0,
00521 7, 6, 0, 1, 1, 0, 0,
00522 8, 3, 1, 0, 0, 0, 1,
00523 9, 12, 1, 1, 0, 0, 0,
00524 10, 8, 1, 1, 0, 1, 0,
00525 11, 2, 1, 0, 0, 1, 1,
00526 12, 2, 1, 1, 1, 0, 0,
00527 13, 1, 0, 1, 0, 1, 1,
00528 14, 4, 1, 0, 1, 0, 0,
00529 15, 4, 0, 1, 0, 0, 1,
00530 16, 1, 1, 1, 0, 1, 1,
00531 17, 2, 1, 0, 1, 1, 0,
00532 18, 1, 0, 0, 0, 0, 1,
00533 19, 1, 1, 1, 1, 1, 0,
00534 20, 1, 1, 1, 0, 0, 1,
00535 21, 1, 0, 1, 1, 1, 0,
00536 };
00537
00538
00539
00540
00541 const int p3[] = {
00542 100, 5, 25,
00543 1, 2, 1, 2, 1,
00544 2, 3, 3, 5, 5,
00545 0, 7, 1, 0, 0, 1, 0,
00546 1, 11, 1, 1, 0, 0, 0,
00547 2, 1, 0, 1, 1, 1, 1,
00548 3, 3, 1, 0, 1, 0, 0,
00549 4, 15, 0, 1, 0, 0, 0,
00550 5, 2, 1, 0, 1, 1, 0,
00551 6, 8, 0, 1, 0, 1, 0,
00552 7, 5, 0, 0, 1, 0, 0,
00553 8, 3, 0, 0, 0, 1, 0,
00554 9, 4, 0, 1, 1, 1, 0,
00555 10, 5, 1, 0, 0, 0, 0,
00556 11, 2, 1, 1, 1, 0, 1,
00557 12, 6, 0, 1, 1, 0, 0,
00558 13, 2, 0, 0, 1, 0, 1,
00559 14, 2, 0, 1, 0, 0, 1,
00560 15, 4, 1, 1, 1, 1, 0,
00561 16, 3, 1, 0, 0, 0, 1,
00562 17, 5, 1, 1, 0, 1, 0,
00563 18, 2, 1, 1, 1, 0, 0,
00564 19, 4, 1, 1, 0, 0, 1,
00565 20, 1, 1, 0, 0, 1, 1,
00566 21, 1, 1, 1, 0, 1, 1,
00567 22, 1, 0, 1, 0, 1, 1,
00568 23, 1, 0, 1, 1, 0, 1,
00569 24, 2, 0, 0, 0, 0, 1,
00570 };
00571
00572
00573
00574
00575 const int p4[] = {
00576 100, 5, 26,
00577 1, 2, 1, 2, 1,
00578 2, 3, 3, 5, 5,
00579 0, 10, 1, 0, 0, 0, 0,
00580 1, 2, 0, 0, 0, 0, 1,
00581 2, 8, 0, 1, 0, 1, 0,
00582 3, 8, 0, 0, 0, 1, 0,
00583 4, 6, 0, 1, 1, 0, 0,
00584 5, 11, 0, 1, 0, 0, 0,
00585 6, 3, 0, 0, 1, 0, 0,
00586 7, 2, 0, 0, 1, 1, 0,
00587 8, 7, 1, 1, 0, 0, 0,
00588 9, 2, 1, 0, 0, 1, 1,
00589 10, 4, 1, 0, 1, 0, 0,
00590 11, 7, 1, 0, 0, 1, 0,
00591 12, 1, 1, 1, 1, 0, 1,
00592 13, 3, 0, 1, 1, 1, 0,
00593 14, 4, 0, 1, 0, 0, 1,
00594 15, 5, 1, 1, 1, 0, 0,
00595 16, 2, 1, 1, 0, 0, 1,
00596 17, 1, 1, 0, 1, 1, 1,
00597 18, 2, 1, 0, 1, 1, 0,
00598 19, 3, 1, 0, 0, 0, 1,
00599 20, 2, 0, 1, 1, 0, 1,
00600 21, 1, 0, 1, 0, 1, 1,
00601 22, 3, 1, 1, 0, 1, 0,
00602 23, 1, 0, 0, 1, 1, 1,
00603 24, 1, 1, 1, 1, 1, 1,
00604 25, 1, 1, 1, 1, 1, 0,
00605 };
00606
00607
00608
00609
00610 const int p5[] = {
00611 100, 5, 23,
00612 1, 2, 1, 2, 1,
00613 2, 3, 3, 5, 5,
00614 0, 2, 0, 0, 0, 1, 1,
00615 1, 2, 0, 0, 1, 0, 1,
00616 2, 5, 0, 1, 1, 1, 0,
00617 3, 4, 0, 0, 0, 1, 0,
00618 4, 4, 0, 1, 0, 1, 0,
00619 5, 1, 1, 1, 0, 0, 1,
00620 6, 3, 1, 1, 1, 0, 1,
00621 7, 4, 0, 0, 1, 0, 0,
00622 8, 19, 0, 1, 0, 0, 0,
00623 9, 7, 1, 1, 0, 1, 0,
00624 10, 10, 1, 0, 0, 0, 0,
00625 11, 1, 0, 0, 1, 1, 0,
00626 12, 5, 1, 1, 1, 1, 0,
00627 13, 2, 1, 0, 1, 1, 0,
00628 14, 6, 1, 1, 0, 0, 0,
00629 15, 4, 1, 1, 1, 0, 0,
00630 16, 8, 1, 0, 0, 1, 0,
00631 17, 1, 1, 0, 0, 0, 1,
00632 18, 4, 0, 1, 1, 0, 0,
00633 19, 2, 0, 0, 0, 0, 1,
00634 20, 4, 0, 1, 0, 0, 1,
00635 21, 1, 1, 1, 0, 1, 1,
00636 22, 1, 0, 1, 1, 0, 1,
00637 };
00638
00639 const int* problems[] = {
00640 &p0[0],
00641 &p1[0],
00642 &p2[0],
00643 &p3[0],
00644 &p4[0],
00645 &p5[0],
00646 };
00647
00649 const unsigned int n_problems = sizeof(problems)/sizeof(int*);
00650 };
00651
00652
00653