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/set.hh"
00039 #include "examples/support.hh"
00040
00047
00048 struct Tournament {
00050 int groups;
00052 int playersInGroup;
00054 int weeks;
00055 };
00057 static const Tournament t[]=
00058 { {8,4,9},
00059 {5,3,7},
00060 {4,3,2}
00061 };
00063 static const unsigned int n_examples = sizeof(t) / sizeof(Tournament);
00065
00074 class Golf : public Example {
00075 public:
00077 enum {
00078 MODEL_PLAIN,
00079 MODEL_SYMMETRY
00080 };
00081 enum {
00082 PROP_PLAIN,
00083 PROP_DECOMPOSE
00084 };
00085 int groups;
00086 int playersInGroup;
00087 int weeks;
00088 int players;
00089
00091 SetVarArray groupsS;
00092
00094 SetVar& group(int w, int g) {
00095 return groupsS[w*groups+g];
00096 }
00097
00099 Golf(const SizeOptions& opt) :
00100 groups(t[opt.size()].groups),
00101 playersInGroup(t[opt.size()].playersInGroup),
00102 weeks(t[opt.size()].weeks),
00103 players(groups*playersInGroup),
00104 groupsS(this,groups*weeks,IntSet::empty,0,players-1,
00105 playersInGroup,playersInGroup) {
00106
00107 SetVar allPlayers(this, 0, players-1, 0, players-1);
00108
00109
00110 for (int w=0; w<weeks; w++) {
00111 SetVarArgs p(groups);
00112 for (int g=0; g < groups; g++)
00113 p[g] = group(w,g);
00114
00115 rel(this,SOT_DUNION,p,allPlayers);
00116 }
00117
00118
00119 for (int w=0; w<weeks; w++) {
00120 for (int g=0; g<groups; g++) {
00121 SetVar v = group(w,g);
00122 SetVar vcompl;
00123 if (opt.propagation() == PROP_DECOMPOSE) {
00124 vcompl = SetVar(this,IntSet::empty,
00125 Set::Limits::min,Set::Limits::max);
00126 rel(this, v, SRT_CMPL, vcompl);
00127 }
00128 for (int i=(w+1)*groups; i<weeks*groups; i++) {
00129 if (opt.propagation() == PROP_PLAIN) {
00130 SetVar atMostOne(this,IntSet::empty,0,players-1,0,1);
00131 rel(this, v, SOT_INTER, groupsS[i], SRT_EQ, atMostOne);
00132 } else {
00133 SetVar atMostOneC(this,IntSet::empty,
00134 Set::Limits::min,
00135 Set::Limits::max,
00136 Set::Limits::card-1,
00137 Set::Limits::card);
00138 SetVar groupsSiC(this,IntSet::empty,
00139 Set::Limits::min,Set::Limits::max);
00140 rel(this, groupsS[i], SRT_CMPL, groupsSiC);
00141 rel(this, vcompl, SOT_UNION, groupsSiC, SRT_EQ, atMostOneC);
00142 }
00143 }
00144 }
00145 }
00146
00147 if (opt.model() == MODEL_SYMMETRY) {
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 for (int w=0; w < weeks; w++) {
00159 for (int p=0; p < players; p++) {
00160 BoolVarArgs bs(groups);
00161 for (int g=0; g<groups; g++) {
00162 BoolVar b(this,0,1);
00163 dom(this, group(w,g), SRT_SUP, p, b);
00164 bs[g] = b;
00165 }
00166 linear(this, bs, IRT_EQ, 1);
00167 }
00168 }
00169
00170
00171
00172 atmostOne(this, groupsS, playersInGroup);
00173
00174
00175 for (int w=0; w<weeks; w++) {
00176 for (int g=0; g<groups-1; g++) {
00177 IntVar minG1(this, 0, players-1);
00178 IntVar minG2(this, 0, players-1);
00179 SetVar g1 = group(w,g);
00180 SetVar g2 = group(w,g+1);
00181 min(this, g1, minG1);
00182 min(this, g2, minG2);
00183 rel(this, minG1, IRT_LE, minG2);
00184 }
00185 }
00186
00187
00188
00189 for (int w=0; w<weeks-1; w++) {
00190 SetVar g1(this, IntSet::empty, 1, players-1);
00191 SetVar g2(this, IntSet::empty, 1, players-1);
00192 rel(this, g1, SOT_DUNION, IntSet(0,0), SRT_EQ, group(w,0));
00193 rel(this, g2, SOT_DUNION, IntSet(0,0), SRT_EQ, group(w+1,0));
00194 IntVar minG1(this, 0, players-1);
00195 IntVar minG2(this, 0, players-1);
00196 min(this, g1, minG1);
00197 min(this, g2, minG2);
00198 rel(this, minG1, IRT_LE, minG2);
00199 }
00200
00201
00202
00203 IntVarArray groupsSInv(this, weeks*players, 0, groups-1);
00204 for (int w=0; w<weeks; w++) {
00205 for (int p=0; p<players; p++) {
00206 SetVar thisPlayer(this, p,p, 0, players-1);
00207 SetVarArgs thisWeek(groups);
00208 for (int g=0; g<groups; g++)
00209 thisWeek[g] = group(w,g);
00210 element(this, thisWeek, groupsSInv[w*players+p], thisPlayer);
00211 }
00212 }
00213
00214
00215
00216 for (int w=0; w<weeks; w++) {
00217 for (int p=0; p<groups; p++) {
00218 rel(this, groupsSInv[w*players+p], IRT_LQ, p);
00219 }
00220 }
00221
00222 }
00223
00224 branch(this, groupsS, SET_VAR_MIN_UNKNOWN_ELEM, SET_VAL_MIN);
00225 }
00226
00228 virtual void
00229 print(std::ostream& os) {
00230 os << "Tournament plan" << std::endl;
00231
00232 for (int w=0; w<weeks; w++) {
00233 os << "Week " << w << ": " << std::endl << " ";
00234 for (int g=0; g<groups; g++) {
00235 if (group(w,g).assigned()) {
00236 bool first = true;
00237 os << "(";
00238 for (SetVarGlbValues glb(group(w,g)); glb(); ++glb) {
00239 if (first) first = false; else os << " ";
00240 os << glb.val();
00241 }
00242 os << ")";
00243 } else {
00244 os << "(" << group(w,g) << ")";
00245 }
00246 if (g < groups-1) os << " ";
00247 if (g > 0 && g % 4 == 0) os << std::endl << " ";
00248 }
00249 os << std::endl;
00250 }
00251 }
00252
00254 Golf(bool share, Golf& s) : Example(share,s),
00255 groups(s.groups), playersInGroup(s.playersInGroup),
00256 weeks(s.weeks), players(s.players) {
00257 groupsS.update(this, share, s.groupsS);
00258 }
00260 virtual Space*
00261 copy(bool share) {
00262 return new Golf(share,*this);
00263 }
00264
00266 virtual void
00267 getVars(Gecode::Reflection::VarMap& vm, bool registerOnly) {
00268 vm.putArray(this, groupsS, "groupsS", registerOnly);
00269 }
00270 };
00271
00275 int
00276 main(int argc, char* argv[]) {
00277 SizeOptions opt("Golf");
00278 opt.model(Golf::MODEL_PLAIN);
00279 opt.model(Golf::MODEL_PLAIN, "none", "no symmetry breaking");
00280 opt.model(Golf::MODEL_SYMMETRY, "symmetry", "static symmetry breaking");
00281 opt.propagation(Golf::PROP_PLAIN);
00282 opt.propagation(Golf::PROP_PLAIN, "plain", "intersection constraints");
00283 opt.propagation(Golf::PROP_DECOMPOSE, "decompose",
00284 "union and complement constraints");
00285 opt.solutions(1);
00286 opt.parse(argc,argv);
00287 if (opt.size() >= n_examples) {
00288 std::cerr << "Error: size must be between 0 and " << n_examples - 1
00289 << std::endl;
00290 return 1;
00291 }
00292 Example::run<Golf,DFS,SizeOptions>(opt);
00293 return 0;
00294 }
00295
00296
00297