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
00046 #include <algorithm>
00047 #include <iomanip>
00048
00049 using namespace Gecode;
00050
00052 class Play {
00053 public:
00054 int h;
00055 int a;
00056 int g;
00057
00058 Play(void) : h(0), a(0), g(0) {}
00059 };
00060
00062 class RRS {
00063 protected:
00065 const int teams;
00067 Play* plays;
00069 int weeks(void) const {
00070 return teams-1;
00071 }
00073 int periods(void) const {
00074 return teams/2;
00075 }
00077 int gn(int h, int a) const {
00078 return teams*(h-1) + a;
00079 }
00081 Play& play(int p, int w) {
00082 return plays[p*weeks() + w];
00083 }
00084 public:
00110 RRS(int t) : teams(t), plays(new Play[periods()*weeks()]) {
00111
00112 play(0,0).h = 1;
00113 play(0,0).a = 2;
00114 play(0,0).g = 2;
00115
00116
00117 for (int p=1; p<periods(); p++) {
00118 play(p,0).h = (p + 1) + 1;
00119 play(p,0).a = teams - (p + 1 - 2);
00120 play(p,0).g = gn(play(p,0).h,play(p,0).a);
00121 }
00122
00123
00124 for (int w=1; w<weeks(); w++) {
00125 for (int p=0; p<periods(); p++) {
00126 if (play(p,w-1).h == teams)
00127 play(p,w).h = 2;
00128 else if (play(p,w-1).h == 1)
00129 play(p,w).h = 1;
00130 else
00131 play(p,w).h = play(p,w-1).h + 1;
00132 if (play(p,w-1).a == teams)
00133 play(p,w).a = 2;
00134 else
00135 play(p,w).a = play(p,w-1).a + 1;
00136
00137
00138 if (play(p,w).h > play(p,w).a)
00139 std::swap(play(p,w).h,play(p,w).a);
00140
00141 play(p,w).g = gn(play(p,w).h,play(p,w).a);
00142 }
00143 }
00144
00145 }
00147 void hag(int w, IntArgs& h, IntArgs& a, IntArgs& g) {
00148 for (int p=0; p<periods(); p++) {
00149 h[p] = play(p,w).h;
00150 a[p] = play(p,w).a;
00151 g[p] = play(p,w).g;
00152 }
00153 }
00155 ~RRS(void) {
00156 delete [] plays;
00157 }
00158 };
00159
00160
00161
00178 class SportsLeague : public Script {
00179 protected:
00180 const int teams;
00181 IntVarArray home;
00182 IntVarArray away;
00183 IntVarArray game;
00184
00186 int weeks(void) const {
00187 return teams-1;
00188 }
00190 int periods(void) const {
00191 return teams/2;
00192 }
00194 IntVar& h(int p, int w) {
00195 return home[p*teams + w];
00196 }
00198 const IntVar& h(int p, int w) const {
00199 return home[p*teams + w];
00200 }
00202 IntVar& a(int p, int w) {
00203 return away[p*teams + w];
00204 }
00206 const IntVar& a(int p, int w) const {
00207 return away[p*teams + w];
00208 }
00210 IntVar& g(int p, int w) {
00211 return game[p*weeks() + w];
00212 }
00214 const IntVar& g(int p, int w) const {
00215 return game[p*weeks() + w];
00216 }
00217
00218 public:
00220 SportsLeague(const SizeOptions& opt) :
00221 teams(opt.size()),
00222 home(*this, periods() * teams, 1, weeks()),
00223 away(*this, periods() * teams, 2, weeks()+1),
00224 game(*this, weeks()*periods(), 2, teams*weeks())
00225 {
00226
00227 RRS r(teams);
00228
00229
00230 for (int w=0; w<weeks(); w++) {
00231 IntArgs rh(periods()), ra(periods()), rg(periods());
00232 IntVarArgs n(*this,periods(),0,periods()-1);
00233
00234 distinct(*this, n, opt.icl());
00235
00236 r.hag(w,rh,ra,rg);
00237
00238 for (int p=0; p<periods(); p++) {
00239 element(*this, rh, n[p], h(p,w));
00240 element(*this, ra, n[p], a(p,w));
00241 element(*this, rg, n[p], g(p,w));
00242 }
00243 }
00244
00246 for (int p=0; p<periods(); p++)
00247 for (int w=0; w<teams; w++)
00248 rel(*this, h(p,w), IRT_LE, a(p,w));
00249
00250
00251 {
00252 IntVarArgs h0(periods());
00253 for (int p=0; p<periods(); p++)
00254 h0[p] = h(p,0);
00255 rel(*this, h0, IRT_LE);
00256 }
00257
00258
00259 rel(*this, h(0,0), IRT_EQ, 1);
00260 rel(*this, a(0,0), IRT_EQ, 2);
00261
00263 for (int w=0; w<teams; w++) {
00264 IntVarArgs c(teams);
00265 for (int p=0; p<periods(); p++) {
00266 c[2*p] = h(p,w); c[2*p+1] = a(p,w);
00267 }
00268 distinct(*this, c, opt.icl());
00269 }
00270
00272 for (int p=0; p<periods(); p++) {
00273 IntVarArgs r(2*teams);
00274 for (int t=0; t<teams; t++) {
00275 r[2*t] = h(p,t);
00276 r[2*t+1] = a(p,t);
00277 }
00278 IntArgs values(teams);
00279 for (int i=1; i<=teams; i++)
00280 values[i-1] = i;
00281 count(*this, r, IntSet(2,2), values, opt.icl());
00282 }
00283
00284
00285 for (int p=0; p<periods(); p++)
00286 for (int w=0; w<weeks(); w ++)
00287 rel(*this, teams * h(p,w) + a(p,w) - g(p,w) == teams);
00288
00289 distinct(*this, game, opt.icl());
00290
00291 branch(*this, game, INT_VAR_NONE, INT_VAL_SPLIT_MIN);
00292 }
00294 SportsLeague(bool share, SportsLeague& s)
00295 : Script(share, s), teams(s.teams) {
00296 home.update(*this, share, s.home);
00297 away.update(*this, share, s.away);
00298 game.update(*this, share, s.game);
00299 }
00301 virtual Space*
00302 copy(bool share) {
00303 return new SportsLeague(share, *this);
00304 }
00306 virtual void print(std::ostream& os) const {
00307
00308 os << "\t ";
00309 for (int p=0; p<periods(); p++) {
00310 os << "P[";
00311 os.width(2);
00312 os << p << "] ";
00313 }
00314 os << std::endl;
00315
00316 for (int w=0; w<weeks(); w++) {
00317 os << "\tW[";
00318 os.width(2);
00319 os << w+1 << "]: ";
00320 for (int p=0; p<periods(); p++) {
00321 os.width(2);
00322 os << h(p,w).val() << '-';
00323 os.width(2);
00324 os << a(p,w).val() << " ";
00325 }
00326 os << std::endl;
00327 }
00328 }
00329 };
00330
00331
00335 int
00336 main(int argc, char* argv[]) {
00337 SizeOptions opt("Sports League Scheduling");
00338 opt.icl(ICL_DOM);
00339 opt.size(18);
00340 opt.parse(argc,argv);
00341 if (opt.size() < 5) {
00342 std::cerr<< "No Solution for less than 5 teams!" << std::endl;
00343 return 1;
00344 }
00345 if (opt.size() % 2 != 0) {
00346 std::cerr << "Number of teams has to be even!" << std::endl;
00347 return 1;
00348 }
00349 Script::run<SportsLeague, DFS,SizeOptions>(opt);
00350 return 0;
00351 }
00352
00353