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 #include <gecode/int/gcc.hh>
00041 #include <gecode/int/distinct.hh>
00042
00043 namespace Gecode { namespace Int { namespace GCC {
00044
00055 template<class Card, bool isView>
00056 inline bool
00057 check_alldiff(int n, ViewArray<Card>& k){
00058 if (isView) {
00059 if (k.size() == n) {
00060 for (int i=k.size(); i--;)
00061 if (k[i].min() != 1 || k[i].max() != 1)
00062 return false;
00063 return true;
00064 }
00065 return false;
00066 } else {
00067 for (int i=k.size(); i--;)
00068 if (k[i].min() != 0 || k[i].max() != 1)
00069 return false;
00070 return true;
00071 }
00072 }
00073
00078 template <class View>
00079 forceinline unsigned int
00080 x_card(Space& home, ViewArray<View>& x) {
00081 int n = x.size();
00082 Region r(home);
00083 ViewRanges<View>* xrange = r.alloc<ViewRanges<View> >(n);
00084 for (int i = n; i--; ){
00085 ViewRanges<View> iter(x[i]);
00086 xrange[i] = iter;
00087 }
00088
00089 Iter::Ranges::NaryUnion<ViewRanges<View> > drl(&xrange[0], x.size());
00090 return Iter::Ranges::size(drl);
00091 }
00092
00093
00101 template<class Card, bool isView>
00102 inline ExecStatus
00103 card_cons(Space& home, ViewArray<Card>& k, int n) {
00104
00105 int smin = 0;
00106 int smax = 0;
00107 int m = k.size();
00108 for (int i = m; i--; ) {
00109 int ci = k[i].counter();
00110 if (ci > k[i].max() ) {
00111
00112 return ES_FAILED;
00113 } else {
00114 smax += (k[i].max() - ci);
00115 if (ci < k[i].min()) {
00116 smin += (k[i].min() - ci);
00117 }
00118 }
00119 if (k[i].min() > n) {
00120
00121 return ES_FAILED;
00122 }
00123 if (!k[i].assigned()) {
00124 ModEvent me = k[i].lq(home, n);
00125 if (me_failed(me)) {
00126 return ES_FAILED;
00127 }
00128 }
00129 }
00130
00131 if (n < smin) {
00132
00133 return ES_FAILED;
00134 }
00135
00136
00137 if (smax < n) {
00138
00139 return ES_FAILED;
00140 }
00141 return ES_OK;
00142 }
00143
00149 template<class Card, bool isView>
00150 inline void
00151 post_template(Space& home, ViewArray<IntView>& x, ViewArray<Card>& k,
00152 IntConLevel& icl){
00153 int n = static_cast<int>(x_card(home, x));
00154 bool rewrite = false;
00155 rewrite = check_alldiff<Card,isView>(n, k);
00156 GECODE_ES_FAIL(home, (card_cons<Card, isView>(home, k, x.size())));
00157 if (rewrite) {
00158 if (x.same(home))
00159 throw ArgumentSame("Int::distinct");
00160 if (home.failed()) return;
00161 switch (icl) {
00162 case ICL_BND:
00163 GECODE_ES_FAIL(home,Distinct::Bnd<IntView>::post(home,x));
00164 break;
00165 case ICL_DOM:
00166 GECODE_ES_FAIL(home,Distinct::Dom<IntView>::post(home,x));
00167 break;
00168 default:
00169 GECODE_ES_FAIL(home,Distinct::Val<IntView>::post(home,x));
00170 }
00171 } else {
00172 switch (icl) {
00173 case ICL_BND: {
00174 GECODE_ES_FAIL(home, (GCC::Bnd<IntView, Card, isView>::post(home, x, k)));
00175 break;
00176 }
00177 case ICL_DOM: {
00178 GECODE_ES_FAIL(home, (GCC::Dom<IntView, Card, isView>::post(home, x, k)));
00179 break;
00180 }
00181 default: {
00182 GECODE_ES_FAIL(home, (GCC::Val<IntView, Card, isView>::post(home, x, k)));
00183 }
00184 }
00185 }
00186 }
00187
00188 }}
00189
00190 using namespace Int;
00191 using namespace Int::GCC;
00192 using namespace Support;
00193
00194
00195
00196 void count(Space& home, const IntVarArgs& x,
00197 const IntVarArgs& c, const IntArgs& v,
00198 IntConLevel icl) {
00199
00200
00201
00202
00203 int vsize = v.size();
00204 int csize = c.size();
00205 if (vsize != csize)
00206 throw ArgumentSizeMismatch("Int::count");
00207 if (x.same(home))
00208 throw ArgumentSame("Int::count");
00209
00210 if (home.failed())
00211 return;
00212
00213 ViewArray<IntView> xv(home, x);
00214
00215
00216 IntSet valid(&v[0], vsize);
00217
00218
00219
00220 for (int i = xv.size(); i--; ) {
00221 IntSetRanges ir(valid);
00222 GECODE_ME_FAIL(home, xv[i].inter_r(home, ir));
00223 }
00224
00225 linear(home, c, IRT_EQ, xv.size());
00226
00227 ViewArray<CardView> cv(home, c);
00228
00229
00230 for (int i = vsize; i--; ) {
00231 cv[i].card(v[i]);
00232 cv[i].counter(0);
00233 }
00234 GCC::post_template<CardView, true>(home, xv, cv, icl);
00235 }
00236
00237
00238 void count(Space& home, const IntVarArgs& x, const IntVarArgs& c,
00239 IntConLevel icl) {
00240 IntArgs values(c.size());
00241 for (int i = c.size(); i--; )
00242 values[i] = i;
00243 count(home, x, c, values, icl);
00244 }
00245
00246
00247 void count(Space& home, const IntVarArgs& x,
00248 const IntSetArgs& c, const IntArgs& v,
00249 IntConLevel icl) {
00250 int vsize = v.size();
00251 int csize = c.size();
00252 if (vsize != csize)
00253 throw ArgumentSizeMismatch("Int::count");
00254 if (x.same(home))
00255 throw ArgumentSame("Int::count");
00256 for (int i=c.size(); i--; ) {
00257 Limits::check(v[i],"Int::count");
00258 Limits::check(c[i].min(),"Int::count");
00259 Limits::check(c[i].max(),"Int::count");
00260 }
00261
00262 if (home.failed())
00263 return;
00264
00265
00266
00267
00268 ViewArray<IntView> xv(home, x);
00269
00270
00271 IntSet valid(&v[0], vsize);
00272
00273
00274
00275 for (int i = xv.size(); i--; ) {
00276 IntSetRanges ir(valid);
00277 GECODE_ME_FAIL(home, xv[i].inter_r(home, ir));
00278 }
00279
00280 bool hole_found = false;
00281 for (int i = vsize; i--; )
00282 if (c[i].ranges() > 1) {
00283 hole_found = true; break;
00284 }
00285
00286 if (hole_found) {
00287
00288 ViewArray<CardView> cv(home, vsize);
00289 IntVarArgs cvargs(vsize);
00290 for (int i = vsize; i--; ) {
00291 IntVar card(home, c[i]);
00292 cvargs[i] = card;
00293 IntView viewc(card);
00294 cv[i] = viewc;
00295 }
00296
00297
00298 for (int i = vsize; i--; ) {
00299 cv[i].card(v[i]);
00300 cv[i].counter(0);
00301 }
00302
00303 linear(home, cvargs, IRT_EQ, xv.size());
00304
00305 GCC::post_template<CardView, true>(home, xv, cv, icl);
00306 } else {
00307
00308
00309 ViewArray<OccurBndsView> cv(home, csize);
00310
00311 int z = 0;
00312
00313 for (int i = csize; i--; ) {
00314 cv[i].card(v[i]);
00315 cv[i].counter(0);
00316 cv[i].min(c[i].min());
00317 cv[i].max(c[i].max());
00318 if (cv[i].max() == 0){
00319 z++;
00320 }
00321 }
00322
00323
00324 if (z > 0) {
00325
00326 IntArgs rem(z);
00327 z = 0;
00328 for (int j = cv.size(); j--;) {
00329 if (cv[j].max() == 0){
00330 rem[z++] = cv[j].card();
00331 }
00332 }
00333
00334 IntSet remzero(&rem[0], z);
00335 for (int i = xv.size(); i--; ) {
00336 IntSetRanges remzeror(remzero);
00337 GECODE_ME_FAIL(home, xv[i].minus_r(home, remzeror, false));
00338 }
00339
00340 GCC::post_template<OccurBndsView,false>(home, xv, cv, icl);
00341 } else {
00342 GCC::post_template<OccurBndsView,false>(home, xv, cv, icl);
00343 }
00344 }
00345 }
00346
00347
00348 void count(Space& home, const IntVarArgs& x, const IntSetArgs& c,
00349 IntConLevel icl) {
00350 IntArgs values(c.size());
00351 for (int i = c.size(); i--; )
00352 values[i] = i;
00353 count(home, x, c, values, icl);
00354 }
00355
00356 void count(Space& home, const IntVarArgs& x,
00357 const IntSet& c, const IntArgs& v,
00358 IntConLevel icl) {
00359 IntSetArgs cards(v.size());
00360 for (int i = v.size(); i--; )
00361 cards[i] = c;
00362 count(home, x, cards, v, icl);
00363 }
00364
00365 }
00366
00367