00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "examples/support.hh"
00023 #include "gecode/minimodel.hh"
00024
00031 struct Play {
00033 int h;
00035 int a;
00037 int g;
00038 };
00039
00040 typedef PrimArgArray<Play> RRSArray;
00041
00059 class SportsLeague : public Example {
00060 private:
00063 int t;
00065 int weeks;
00067 int eweeks;
00069 int periods;
00071 int season;
00073 int value;
00075 IntVarArray home;
00077 IntVarArray away;
00079 IntVarArray game;
00081 RRSArray rrs_array;
00082 protected:
00083
00084 int digit(int n) {
00085 int f = n;
00086 int fdigit = 0;
00087 while (f / 10) {
00088 fdigit++;
00089 f = f / 10;
00090 }
00091 return fdigit;
00092 }
00093
00094
00095 void blank(int n) {
00096 for (int d = digit(t) - digit(n); d--; ) {
00097 std::cout << " ";
00098 }
00099 std::cout << n;
00100 }
00101
00102 void blankv(int n) {
00103 for (int d = digit(value) - digit(n); d--; ) {
00104 std::cout << " ";
00105 }
00106 std::cout << n;
00107 }
00108
00109 void blank_only(int n) {
00110 for (int i = digit(n); i--; ) {
00111 std::cout << " ";
00112 }
00113 }
00114
00115 public:
00117 IntVar& h (int p, int w) {
00118 return home[p * eweeks + w];
00119 }
00120
00122 IntVar& a (int p, int w) {
00123 return away[p * eweeks + w];
00124 }
00125
00130 IntVar& g (int p, int w) {
00131 return game[p * weeks + w];
00132 }
00133
00138 Play& rrs(int p, int w) {
00139 return rrs_array[p * weeks + w];
00140 }
00141
00151 int gn(int h, int a) {
00152 return (t * (h - 1) + a);
00153 }
00154
00181 void init_rrs(void) {
00182
00183
00184 for(int p = 0; p < periods; p++)
00185 for (int w = 0; w < weeks; w++) {
00186 rrs(p, w).h = 0;
00187 rrs(p, w).a = 0;
00188 rrs(p, w).g = 0;
00189 }
00190
00191
00192 rrs(0, 0).h = 1;
00193 rrs(0, 0).a = 2;
00194 rrs(0, 0).g = 2;
00195
00196
00197 for(int p = 1; p < periods; p++){
00198 rrs(p, 0).h = (p + 1) + 1;
00199 rrs(p, 0).a = t - (p + 1 - 2);
00200 rrs(p, 0).g = gn(rrs(p, 0).h, rrs(p, 0).a);
00201 }
00202
00203
00204 for (int w = 1; w < weeks; w++) {
00205 for (int p = 0; p < periods; p++) {
00206 if (rrs(p, w - 1).h == t) {
00207 rrs(p, w).h = 2;
00208 } else {
00209 if (rrs(p, w - 1).h == 1) {
00210 rrs(p, w).h = 1;
00211 } else {
00212 rrs(p, w).h = rrs(p, w - 1).h + 1;
00213 }
00214 }
00215 if (rrs(p, w - 1).a == t) {
00216 rrs(p, w).a = 2;
00217 } else {
00218 rrs(p, w).a = rrs(p, w - 1).a + 1;
00219 }
00220
00221
00222 if (rrs(p, w).h > rrs(p, w).a) {
00223 int buffer = rrs(p, w).h;
00224 rrs(p, w).h = rrs(p, w).a;
00225 rrs(p, w).a = buffer;
00226 }
00227 rrs(p, w).g = gn(rrs(p, w).h, rrs(p, w).a);
00228 }
00229 }
00230 }
00231
00232 SportsLeague(const Options& op) :
00233 t (op.size),
00234 weeks (t - 1),
00235 eweeks (t),
00236 periods (t / 2),
00237 season (weeks * periods),
00238 value (t * (t - 2) + t),
00239 home (this, periods * eweeks),
00240 away (this, periods * eweeks),
00241 game (this, season),
00242 rrs_array (periods * weeks){
00243
00244 IntSet dom_all (1, t);
00245 IntSet dom_game (2, value);
00246 IntSet dom_home (1, t - 1);
00247 IntSet dom_away (2, t);
00248 IntSet dom_index (0, periods - 1);
00249
00250 for (int i = eweeks * periods; i--; ) {
00251 home[i].init(this, dom_home);
00252 away[i].init(this, dom_away);
00253 }
00254 for (int i = season; i--; ) {
00255 game[i].init(this, dom_game);
00256 }
00257
00258
00259
00260 init_rrs();
00261
00262
00263 for (int w = 0; w < weeks; w++) {
00264 IntArgs gamenum(periods);
00265 IntArgs fst(periods);
00266 IntArgs snd(periods);
00267
00268 for(int p = 0; p < periods; p++){
00269 gamenum[p] = rrs(p, w).g;
00270 fst[p] = rrs(p, w).h;
00271 snd[p] = rrs(p, w).a;
00272 }
00273
00274 IntVarArray n(this, periods, 0, periods - 1);
00275 distinct(this, n, ICL_DOM);
00276
00277 for(int p = 0; p < periods; p++){
00278 element(this, gamenum, n[p], g(p, w), op.icl);
00279 element(this, fst, n[p], h(p, w), op.icl);
00280 element(this, snd, n[p], a(p, w), op.icl);
00281 }
00282 }
00283
00284
00291
00292 rel(this, h(0,0), IRT_EQ, 1);
00293 rel(this, a(0,0), IRT_EQ, 2);
00294
00295 for (int p = 0; p < periods; p++) {
00296 for (int w = 0; w < eweeks; w++) {
00297 rel(this, h(p, w), IRT_LE, a(p, w));
00298 }
00299 }
00300
00301
00302 for (int p = 0; p < periods - 1; p++) {
00303 rel(this, h(p, 0), IRT_LE, h(p + 1, 0));
00304 }
00305
00312 for(int w = 0; w < eweeks; w++ ) {
00313 IntVarArray col(this, t);
00314 int k = 0;
00315 for( int p = 0; p < periods; p++ ) {
00316 col[k] = h(p, w);
00317 k++;
00318 col[k] = a(p, w);
00319 k++;
00320 }
00321 distinct(this, col, ICL_DOM);
00322 }
00323
00332 for(int p = 0; p < periods; p++) {
00333 IntVarArray row(this, 2 * eweeks);
00334 for (int w = 0; w < 2 * eweeks; w +=2) {
00335 row[w] = h(p, w / 2);
00336 row[w + 1] = a(p, w / 2);
00337 }
00338 gcc(this, row, 2, op.icl);
00339 }
00340
00341
00342
00343 for(int p = 0; p < periods; p++) {
00344 for(int w = 0; w < weeks; w ++) {
00345 post(this, t * h(p, w) + 1 * a(p, w) - 1* g(p, w) == t);
00346 }
00347 }
00348
00349 distinct(this, game, ICL_DOM);
00350
00351 branch(this, game, BVAR_NONE, BVAL_MIN);
00352
00353 }
00354
00355 SportsLeague(bool share, SportsLeague& s)
00356 : Example(share, s),
00357 t(s.t), weeks(s.weeks), eweeks(s.eweeks),
00358 periods(s.periods), season(s.season),
00359 value(s.value), rrs_array(s.rrs_array) {
00360 home.update(this, share, s.home);
00361 away.update(this, share, s.away);
00362 game.update(this, share, s.game);
00363 }
00364
00365 virtual Space*
00366 copy(bool share) {
00367 return new SportsLeague(share, *this);
00368 }
00369
00370 virtual void print(void){
00371
00372
00373 std::cout << "\nSchedule for " << t << " teams"
00374 << " and "<< weeks << " weeks:" << std::endl;
00375
00376 std::cout << " ";
00377 blank_only(t);
00378 std::cout << " ";
00379 for (int p = 0; p < periods; p++) {
00380 blank_only(t);
00381 std::cout << "P[";
00382 blank(p);
00383 std::cout <<"]";
00384 blank_only(t);
00385 }
00386 std::cout <<"\n";
00387
00388
00389 for(int w = 0; w < weeks; w++){
00390 std::cout << "W[";
00391 blank(w + 1);
00392 std::cout <<"]: ";
00393 for(int p = 0; p < periods; p++){
00394 if (h(p, w).assigned() && a(p, w).assigned()) {
00395 std::cout <<" ";
00396 blank(h(p, w).val());
00397 std::cout <<",";
00398 blank(a(p, w).val());
00399 std::cout <<" ";
00400 } else {
00401 blank_only(t);
00402 std::cout << " x ";
00403 blank_only(t);
00404 }
00405 }
00406 std::cout << "\n";
00407 }
00408 std::cout << "\n";
00409
00410
00411 std::cout << "\nUnique game numbers:\n";
00412 std::cout <<"\n";
00413 for(int p = 0; p < periods; p++){
00414 std::cout << "Period[";
00415 blank(p + 1);
00416 std::cout <<"]: " ;
00417 for(int w = 0; w < weeks; w++){
00418 if (g(p, w).assigned()) {
00419 blankv(g(p, w).val());
00420 std::cout << " ";
00421 } else {
00422 for (int i = digit(value); i--; ) {
00423 std::cout << " ";
00424 }
00425 std::cout << " ";
00426 }
00427 }
00428 std::cout << "\n";
00429 }
00430 std::cout << "\n";
00431
00432 }
00433 };
00434
00435
00436 int main(int argc, char** argv){
00437 Options o("Sports League Scheduling ");
00438 o.solutions = 1;
00439 o.size = 18;
00440 o.parse(argc, argv);
00441 if (o.size == 4) {
00442 std::cerr<< "No Solution for t = 4!\n";
00443 return -1;
00444 }
00445 if (o.size % 2 != 0) {
00446 std::cerr << "Number of t has to be even!\n";
00447 return -1;
00448 }
00449 Example::run<SportsLeague, DFS>(o);
00450 return 0;
00451 }
00452
00453
00454