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
00039
00040
00041
00042 #include <gecode/driver.hh>
00043 #include <gecode/int.hh>
00044 #include <gecode/minimodel.hh>
00045 #include <gecode/int/branch.hh>
00046
00047 #include <map>
00048 #include <string>
00049 #include <list>
00050 #include <vector>
00051
00052 using namespace Gecode;
00053
00055 class Course {
00056 public:
00057 const char* name;
00058 int credit;
00059 };
00060
00062 class Curriculum {
00063 public:
00065 int p;
00067 int a;
00069 int b;
00071 int c;
00073 int d;
00074
00076 const Course *courses;
00078 const char **prereqs;
00079 };
00080
00081 namespace {
00082
00083 extern const Curriculum curriculum[];
00084 extern const unsigned int n_examples;
00085
00086 }
00087
00100 class BACP : public MinimizeScript {
00101 protected:
00103 const Curriculum curr;
00104
00106 IntVarArray l;
00108 IntVar u;
00110 IntVarArray q;
00111
00113 IntVarArray x;
00114 public:
00116 enum {
00117 BRANCHING_NAIVE,
00118 BRANCHING_LOAD,
00119 BRANCHING_LOAD_REV,
00120 };
00121
00123 BACP(const SizeOptions& opt) : curr(curriculum[opt.size()]) {
00124 std::map<std::string, int> courseMap;
00125 int maxCredit = 0;
00126 int numberOfCourses = 0;
00127 for (const Course* co=curr.courses; co->name != 0; co++) {
00128 courseMap[co->name] = numberOfCourses++;
00129 maxCredit += co->credit;
00130 }
00131
00132 int p = curr.p;
00133 int a = curr.a;
00134 int b = curr.b;
00135 int c = curr.c;
00136 int d = curr.d;
00137
00138 l = IntVarArray(*this, p, a, b);
00139 u = IntVar(*this, 0, maxCredit);
00140 q = IntVarArray(*this, p, c, d);
00141 x = IntVarArray(*this, numberOfCourses, 0, p-1);
00142
00143 for (int j=0; j<p; j++) {
00144 BoolVarArgs xij(*this, numberOfCourses, 0, 1);
00145 IntArgs t(numberOfCourses);
00146 for (int i=0; i<numberOfCourses; i++) {
00147 rel(*this, (x[i]==j) == xij[i]);
00148 t[i] = curr.courses[i].credit;
00149 }
00150
00151 linear(*this, t, xij, IRT_EQ, l[j]);
00152
00153 linear(*this, xij, IRT_EQ, q[j]);
00154 }
00155
00156
00157 for (const char** prereq = curr.prereqs; *prereq != 0; prereq+=2)
00158 rel(*this, x[courseMap[*prereq]] < x[courseMap[*(prereq+1)]]);
00159
00160
00161 max(*this, l, u);
00162
00163
00164 linear(*this, l, IRT_EQ, maxCredit);
00165 linear(*this, q, IRT_EQ, numberOfCourses);
00166
00167 if (opt.branching() == BRANCHING_NAIVE) {
00168 branch(*this, x, INT_VAR_SIZE_MIN, INT_VAL_MIN);
00169 } else {
00170 Int::Branch::BySizeMin varsel(*this, VarBranchOptions::def);
00171 ViewArray<Int::IntView> xv(*this, IntVarArgs(x));
00172 if (opt.branching() == BRANCHING_LOAD) {
00173 ValBestLoad<true> valsel(*this, ValBranchOptions::def);
00174 ViewValBrancher<Int::Branch::BySizeMin, ValBestLoad<true> >
00175 ::post(*this,xv,varsel,valsel);
00176 } else {
00177 ValBestLoad<false> valsel(*this, ValBranchOptions::def);
00178 ViewValBrancher<Int::Branch::BySizeMin, ValBestLoad<false> >
00179 ::post(*this,xv,varsel,valsel);
00180 }
00181 }
00182 }
00183
00185 BACP(bool share, BACP& bacp) : MinimizeScript(share,bacp),
00186 curr(bacp.curr) {
00187 l.update(*this, share, bacp.l);
00188 u.update(*this, share, bacp.u);
00189 x.update(*this, share, bacp.x);
00190 }
00192 virtual Space*
00193 copy(bool share) {
00194 return new BACP(share,*this);
00195 }
00197 virtual IntVar cost(void) const {
00198 return u;
00199 }
00201 virtual void
00202 print(std::ostream& os) const {
00203 std::vector<std::list<int> > period(curr.p);
00204 for (int i=x.size(); i--;)
00205 period[x[i].val()].push_back(i);
00206
00207 os << "Solution with load " << u.val() << ":" << std::endl;
00208 for (int i=0; i<curr.p; i++) {
00209 os << "\tPeriod "<<i+1<<": ";
00210 for (std::list<int>::iterator v=period[i].begin();
00211 v != period[i].end(); ++v) {
00212 os << curr.courses[*v].name << " ";
00213 }
00214 os << std::endl;
00215 }
00216 os << std::endl;
00217 }
00218
00225 template <bool minimize>
00226 class ValBestLoad : public ValSelBase<Int::IntView,int> {
00227 public:
00229 ValBestLoad(void) {}
00230
00232 ValBestLoad(Space& home, const ValBranchOptions& vbo)
00233 : ValSelBase<Int::IntView,int>(home,vbo) {}
00234
00236 int val(Space& home, Int::IntView x) const {
00237 BACP& b = static_cast<BACP&>(home);
00238 Int::ViewValues<Int::IntView> values(x);
00239 int val = -1;
00240 int best = minimize ? Int::Limits::max+1 : Int::Limits::min-1;
00241 while (values()) {
00242 if (minimize
00243 ? b.l[values.val()].min() < best
00244 : b.l[values.val()].min() > best) {
00245 val = values.val();
00246 best = b.l[val].min();
00247 }
00248 ++values;
00249 }
00250 assert(val != -1);
00251 return val;
00252 }
00253
00255 ModEvent tell(Space& home, unsigned int a, Int::IntView x, int n) {
00256 return (a == 0) ? x.eq(home,n) : x.gr(home,n);
00257 }
00258 };
00259 };
00260
00264 int
00265 main(int argc, char* argv[]) {
00266 SizeOptions opt("BACP");
00267 opt.branching(BACP::BRANCHING_NAIVE);
00268 opt.branching(BACP::BRANCHING_NAIVE,"naive");
00269 opt.branching(BACP::BRANCHING_LOAD,"load");
00270 opt.branching(BACP::BRANCHING_LOAD_REV,"load-reverse");
00271 opt.size(2);
00272 opt.solutions(0);
00273 opt.iterations(20);
00274 opt.parse(argc,argv);
00275 if (opt.size() >= n_examples) {
00276 std::cerr << "Error: size must be between 0 and " << n_examples - 1
00277 << std::endl;
00278 return 1;
00279 }
00280 MinimizeScript::run<BACP,BAB,SizeOptions>(opt);
00281 return 0;
00282 }
00283
00284 namespace {
00290
00291 const Course courses8[] =
00292 {
00293 {"dew100", 1},
00294 {"fis100", 3},
00295 {"hcw310", 1},{"iwg101", 2},{"mat190", 4},{"mat192", 4},{"dew101", 1},
00296 {"fis101", 5},{"iwi131", 3},{"mat191", 4},{"mat193", 4},{"fis102", 5},{"hxwxx1", 1},
00297 {"iei134", 3},{"iei141", 3},{"mat194", 4},
00298 {"dewxx0", 1},{"hcw311", 1},{"iei132", 3},{"iei133", 3},{"iei142", 3},{"iei162", 3},
00299 {"iwn170", 3},{"mat195", 3},{"hxwxx2", 1},{"iei231", 4},{"iei241", 4},{"iei271", 3},{"iei281", 3},{"iwn261", 3},
00300 {"hfw120", 2},{"iei233", 4},{"iei238", 3},{"iei261", 3},{"iei272", 3},{"iei273", 3},{"iei161", 3},{"iei232", 3},
00301 {"iei262", 3},{"iei274", 3},{"iwi365", 3},{"iwn270", 3},{"hrw130", 2},{"iei218", 3},{"iei219", 3},{"iei248", 3},
00302 {0,0}
00303 };
00304
00306 const char* prereqs8[] =
00307 {
00308 "dew101","dew100",
00309 "fis101","fis100",
00310 "fis101","mat192",
00311 "mat191","mat190",
00312 "mat193","mat190",
00313 "mat193","mat192",
00314 "fis102","fis101",
00315 "fis102","mat193",
00316 "iei134","iwi131",
00317 "iei141","iwi131",
00318 "mat194","mat191 ",
00319 "mat194","mat193",
00320 "dewxx0","dew101",
00321 "hcw311","hcw310",
00322 "iei132","iei134",
00323 "iei133","iei134",
00324 "iei142","iei141",
00325 "mat195","mat194",
00326 "iei231","iei134",
00327 "iei241","iei142",
00328 "iei271","iei162",
00329 "iei281","mat195",
00330 "iei233","iei231",
00331 "iei238","iei231",
00332 "iei261","iwn261",
00333 "iei272","iei271",
00334 "iei273","iei271",
00335 "iei273","iei271",
00336 "iei161","iwn261",
00337 "iei161","iwn261",
00338 "iei232","iei273",
00339 "iei232","iei273",
00340 "iei262","iwn261",
00341 "iei274","iei273",
00342 "iei274","iei273",
00343 "iei219","iei232",
00344 "iei248","iei233",
00345 "iei248","iei233",
00346 0,0
00347 };
00348
00350 const Course courses10[] = {
00351 {"dew100",1},
00352 {"fis100",3},
00353 {"hrwxx1",2},
00354 {"iwg101",2},
00355 {"mat021",5},
00356 {"qui010",3},
00357 {"dew101",1},
00358 {"fis110",5},
00359 {"hrwxx2",2},
00360 {"iwi131",3},
00361 {"mat022",5},
00362 {"dewxx0",1},
00363 {"fis120",4},
00364 {"hcw310",1},
00365 {"hrwxx3",2},
00366 {"ili134",4},
00367 {"ili151",3},
00368 {"mat023",4},
00369 {"hcw311",1},
00370 {"ili135",4},
00371 {"ili153",3},
00372 {"ili260",3},
00373 {"iwn261",3},
00374 {"mat024",4},
00375 {"fis130",4},
00376 {"ili239",4},
00377 {"ili245",4},
00378 {"ili253",4},
00379 {"fis140",4},
00380 {"ili236",4},
00381 {"ili243",4},
00382 {"ili270",3},
00383 {"ili280",4},
00384 {"ici344",4},
00385 {"ili263",3},
00386 {"ili332",4},
00387 {"ili355",4},
00388 {"iwn170",3},
00389 {"icdxx1",3},
00390 {"ili362",3},
00391 {"iwn270",3},
00392 {"icdxx2",3},
00393 {0,0}
00394 };
00395
00397 const char* prereqs10[] = {
00398 "dew101","dew100",
00399 "fis110","fis100",
00400 "fis110","mat021",
00401 "mat022","mat021",
00402 "dewxx0","dew101",
00403 "fis120","fis110",
00404 "fis120","mat022",
00405 "ili134","iwi131",
00406 "ili151","iwi131",
00407 "mat023","mat022",
00408 "hcw311","hcw310",
00409 "ili135","ili134",
00410 "ili153","ili134",
00411 "ili153","ili151",
00412 "mat024","mat023",
00413 "fis130","fis110",
00414 "fis130","mat022",
00415 "ili239","ili135",
00416 "ili245","ili153",
00417 "ili253","ili153",
00418 "fis140","fis120",
00419 "fis140","fis130",
00420 "ili236","ili239",
00421 "ili243","ili245",
00422 "ili270","ili260",
00423 "ili270","iwn261",
00424 "ili280","mat024",
00425 "ici344","ili243",
00426 "ili263","ili260",
00427 "ili263","iwn261",
00428 "ili332","ili236",
00429 "ili355","ili153",
00430 "ili355","ili280",
00431 "ili362","ili263",
00432 0,0
00433 };
00434
00436 const Course courses12[] = {
00437 {"dew100",1},
00438 {"fis100",3},
00439 {"hcw310",1},
00440 {"iwg101",2},
00441 {"mat111",4},
00442 {"mat121",4},
00443 {"dew101",1},
00444 {"fis110",5},
00445 {"iwi131",3},
00446 {"mat112",4},
00447 {"mat122",4},
00448 {"dewxx0",1},
00449 {"fis120",4},
00450 {"hcw311",1},
00451 {"hxwxx1",1},
00452 {"ili142",4},
00453 {"mat113",4},
00454 {"mat123",4},
00455 {"fis130",4},
00456 {"ili134",4},
00457 {"ili151",3},
00458 {"iwm185",3},
00459 {"mat124",4},
00460 {"fis140",4},
00461 {"hxwxx2",1},
00462 {"ile260",3},
00463 {"ili260",3},
00464 {"iwn170",3},
00465 {"qui104",3},
00466 {"ili231",3},
00467 {"ili243",4},
00468 {"ili252",4},
00469 {"ili273",3},
00470 {"mat210",4},
00471 {"mat260",4},
00472 {"ild208",3},
00473 {"ili221",4},
00474 {"ili274",3},
00475 {"ili281",3},
00476 {"iwn270",3},
00477 {"mat270",4},
00478 {"hrw150",2},
00479 {"ili238",4},
00480 {"ili242",3},
00481 {"ili275",3},
00482 {"ili355",4},
00483 {"hrw110",2},
00484 {"ici393",4},
00485 {"ili237",4},
00486 {"ili334",4},
00487 {"ili363",3},
00488 {"iwn261",3},
00489 {"hrw100",2},
00490 {"ici382",4},
00491 {"ili331",4},
00492 {"ili362",3},
00493 {"ili381",3},
00494 {"iln230",3},
00495 {"ici313",2},
00496 {"ici315",2},
00497 {"ici332",3},
00498 {"ici344",4},
00499 {"icn336",3},
00500 {"iwi365",3},
00501 {"ici314",2},
00502 {"ici367",2},
00503 {0,0}
00504 };
00505
00507 const char* prereqs12[] = {
00508 "dew101","dew100",
00509 "fis110","fis100",
00510 "fis110","mat121",
00511 "mat112","mat111",
00512 "mat122","mat111",
00513 "mat122","mat121",
00514 "dewxx0","dew101",
00515 "fis120","fis110",
00516 "fis120","mat122",
00517 "hcw311","hcw310",
00518 "ili142","iwi131",
00519 "mat113","mat112",
00520 "mat113","mat122",
00521 "mat123","mat112",
00522 "mat123","mat122",
00523 "fis130","fis110",
00524 "fis130","mat122",
00525 "ili134","iwi131",
00526 "ili151","mat112",
00527 "mat124","mat113",
00528 "mat124","mat123",
00529 "fis140","fis120",
00530 "fis140","fis130",
00531 "ile260","fis120",
00532 "ile260","mat124",
00533 "ili231","iwi131",
00534 "ili252","iwi131",
00535 "ili273","ili260",
00536 "mat210","mat113",
00537 "mat260","iwi131",
00538 "mat260","mat113",
00539 "mat260","mat123",
00540 "ili221","ili134",
00541 "ili221","ili231",
00542 "ili221","mat260",
00543 "ili274","ili273",
00544 "ili281","mat260",
00545 "mat270","iwi131",
00546 "mat270","mat113",
00547 "mat270","mat123",
00548 "ili238","ili134",
00549 "ili242","ili142",
00550 "ili275","ili274",
00551 "ili355","ili221",
00552 "hrw110","hrw150",
00553 "ici393","mat210",
00554 "ici393","mat260",
00555 "ili237","ili231",
00556 "ili237","ili252",
00557 "ili334","ili238",
00558 "ili363","ili273",
00559 "hrw100","hrw110",
00560 "ici382","ili334",
00561 "ili331","ili238",
00562 "ili331","ili274",
00563 "ili362","ili363",
00564 "ili381","ili281",
00565 "ili381","mat210",
00566 "iln230","iwn170",
00567 "ici313","ili331",
00568 "ici332","ici393",
00569 "ici332","ili331",
00570 "ici344","ili243",
00571 "icn336","ici393",
00572 "ici314","ici313",
00573 0,0
00574 };
00575
00577 const Curriculum curriculum[]=
00578 { { 8, 10, 24, 2, 10,
00579 courses8, prereqs8
00580 },
00581 { 10, 10, 24, 2, 10,
00582 courses10, prereqs10
00583 },
00584 { 12, 10, 24, 2, 10,
00585 courses12, prereqs12
00586 }
00587 };
00588
00590 const unsigned int n_examples = sizeof(curriculum) / sizeof(Curriculum);
00591
00593 }
00594
00595
00596