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 namespace Gecode { namespace Int { namespace Distinct {
00039
00040 template <class View>
00041 forceinline
00042 Bnd<View>::Bnd(Space* home, ViewArray<View>& x0)
00043 : Propagator(home), x(x0), y(home,x0) {
00044
00045
00046
00047
00048
00049 y.subscribe(home,this,PC_INT_BND);
00050 }
00051
00052 template <class View>
00053 forceinline size_t
00054 Bnd<View>::dispose(Space* home) {
00055 y.cancel(home,this,PC_INT_BND);
00056 (void) Propagator::dispose(home);
00057 return sizeof(*this);
00058 }
00059
00060 template <class View>
00061 forceinline
00062 Bnd<View>::Bnd(Space* home, bool share, Bnd<View>& p)
00063 : Propagator(home,share,p) {
00064 x.update(home,share,p.x);
00065 y.update(home,share,p.y);
00066 }
00067
00068 template <class View>
00069 Actor*
00070 Bnd<View>::copy(Space* home, bool share) {
00071 return new (home) Bnd<View>(home,share,*this);
00072 }
00073
00074 template <class View>
00075 PropCost
00076 Bnd<View>::cost(ModEventDelta med) const {
00077 return (View::me(med) == ME_INT_VAL)
00078 ? cost_lo(y.size(),PC_LINEAR_LO)
00079 : cost_hi(x.size(),PC_LINEAR_HI);
00080 }
00081
00082 template <class View>
00083 Support::Symbol
00084 Bnd<View>::ati(void) {
00085 return Reflection::mangle<View>("Gecode::Int::Distinct::Bnd");
00086 }
00087
00088 template <class View>
00089 Reflection::ActorSpec
00090 Bnd<View>::spec(const Space* home, Reflection::VarMap& m) const {
00091 Reflection::ActorSpec s(ati());
00092 return s << x.spec(home, m);
00093 }
00094
00095
00097 class Rank {
00098 public:
00099 int min, max;
00100 };
00101
00103 template <class View>
00104 class MaxInc {
00105 protected:
00106 ViewArray<View> x;
00107 public:
00108 MaxInc(const ViewArray<View>& x0) : x(x0) {}
00109 forceinline bool
00110 operator()(const int i, const int j) {
00111 return x[i].max() < x[j].max();
00112 }
00113 };
00114
00116 template <class View>
00117 class MinInc {
00118 public:
00119 forceinline bool
00120 operator()(const View& x, const View& y) {
00121 return x.min() < y.min();
00122 }
00123 };
00124
00126 class HallInfo {
00127 public:
00128 int bounds, t, d, h;
00129 };
00130
00131 forceinline void
00132 pathset_t(HallInfo hall[], int start, int end, int to) {
00133 int k, l;
00134 for (l=start; (k=l) != end; hall[k].t=to) {
00135 l = hall[k].t;
00136 }
00137 }
00138
00139 forceinline void
00140 pathset_h(HallInfo hall[], int start, int end, int to) {
00141 int k, l;
00142 for (l=start; (k=l) != end; hall[k].h=to) {
00143 l = hall[k].h;
00144 }
00145 }
00146
00147 forceinline int
00148 pathmin_h(const HallInfo hall[], int i) {
00149 while (hall[i].h < i)
00150 i = hall[i].h;
00151 return i;
00152 }
00153
00154 forceinline int
00155 pathmin_t(const HallInfo hall[], int i) {
00156 while (hall[i].t < i)
00157 i = hall[i].t;
00158 return i;
00159 }
00160
00161 forceinline int
00162 pathmax_h(const HallInfo hall[], int i) {
00163 while (hall[i].h > i)
00164 i = hall[i].h;
00165 return i;
00166 }
00167
00168 forceinline int
00169 pathmax_t(const HallInfo hall[], int i) {
00170 while (hall[i].t > i)
00171 i = hall[i].t;
00172 return i;
00173 }
00174
00175 #define GECODE_INT_MINSORTED(i) (i)
00176 #define GECODE_INT_MAXSORTED(i) (_maxsorted[i])
00177
00178 template <class View>
00179 ExecStatus
00180 prop_bnd(Space* home, ViewArray<View>& x) {
00181 const int n = x.size();
00182
00183 {
00184 MinInc<View> min_inc;
00185 Support::insertion<View,MinInc<View> >(&x[0], n, min_inc);
00186 }
00187
00188 GECODE_AUTOARRAY(int, _maxsorted, n);
00189 for (int i = n; i--; )
00190 _maxsorted[i]=i;
00191
00192 {
00193 MaxInc<View> max_inc(x);
00194 Support::insertion<int,MaxInc<View> >(_maxsorted, n, max_inc);
00195 }
00196
00197
00198 GECODE_AUTOARRAY(HallInfo, hall, 2*n+2);
00199 GECODE_AUTOARRAY(Rank, rank, n);
00200
00201 int nb = 0;
00202 {
00203 int min = x[GECODE_INT_MINSORTED(0)].min();
00204 int max = x[GECODE_INT_MAXSORTED(0)].max() + 1;
00205 int last = min - 2;
00206
00207 hall[0].bounds = last;
00208
00209 int i = 0;
00210 int j = 0;
00211 while (true) {
00212 if ((i < n) && (min < max)) {
00213 if (min != last)
00214 hall[++nb].bounds = last = min;
00215 rank[GECODE_INT_MINSORTED(i)].min = nb;
00216 if (++i < n)
00217 min = x[GECODE_INT_MINSORTED(i)].min();
00218 } else {
00219 if (max != last)
00220 hall[++nb].bounds = last = max;
00221 rank[GECODE_INT_MAXSORTED(j)].max = nb;
00222 if (++j == n)
00223 break;
00224 max = x[GECODE_INT_MAXSORTED(j)].max() + 1;
00225 }
00226 }
00227 hall[nb+1].bounds = hall[nb].bounds + 2;
00228 }
00229
00230
00231 ExecStatus es = ES_FIX;
00232
00233
00234 for (int i=nb+2; --i;) {
00235 hall[i].t = hall[i].h = i-1;
00236 hall[i].d = hall[i].bounds - hall[i-1].bounds;
00237 }
00238 for (int i=0; i<n; i++) {
00239 int x0 = rank[GECODE_INT_MAXSORTED(i)].min;
00240 int z = pathmax_t(hall, x0+1);
00241 int j = hall[z].t;
00242 if (--hall[z].d == 0)
00243 hall[z = pathmax_t(hall, hall[z].t=z+1)].t = j;
00244 pathset_t(hall, x0+1, z, z);
00245 int y = rank[GECODE_INT_MAXSORTED(i)].max;
00246 if (hall[z].d < hall[z].bounds-hall[y].bounds)
00247 return ES_FAILED;
00248 if (hall[x0].h > x0) {
00249 int w = pathmax_h(hall, hall[x0].h);
00250 int m = hall[w].bounds;
00251 ModEvent me = x[GECODE_INT_MAXSORTED(i)].gq(home,m);
00252 if (me_failed(me))
00253 return ES_FAILED;
00254 if ((me == ME_INT_VAL) ||
00255 ((me == ME_INT_BND) && (m != x[GECODE_INT_MAXSORTED(i)].min())))
00256 es = ES_NOFIX;
00257 pathset_h(hall, x0, w, w);
00258 }
00259 if (hall[z].d == hall[z].bounds-hall[y].bounds) {
00260 pathset_h(hall, hall[y].h, j-1, y);
00261 hall[y].h = j-1;
00262 }
00263 }
00264
00265
00266 for (int i=nb+1; i--;) {
00267 hall[i].t = hall[i].h = i+1;
00268 hall[i].d = hall[i+1].bounds - hall[i].bounds;
00269 }
00270 for (int i=n; --i>=0; ) {
00271 int x0 = rank[GECODE_INT_MINSORTED(i)].max;
00272 int z = pathmin_t(hall, x0-1);
00273 int j = hall[z].t;
00274 if (--hall[z].d == 0)
00275 hall[z = pathmin_t(hall, hall[z].t=z-1)].t = j;
00276 pathset_t(hall, x0-1, z, z);
00277 int y = rank[GECODE_INT_MINSORTED(i)].min;
00278 if (hall[z].d < hall[y].bounds-hall[z].bounds)
00279 return ES_FAILED;
00280 if (hall[x0].h < x0) {
00281 int w = pathmin_h(hall, hall[x0].h);
00282 int m = hall[w].bounds - 1;
00283 ModEvent me = x[GECODE_INT_MINSORTED(i)].lq(home,m);
00284 if (me_failed(me))
00285 return ES_FAILED;
00286 if ((me == ME_INT_VAL) ||
00287 ((me == ME_INT_BND) && (m != x[GECODE_INT_MAXSORTED(i)].min())))
00288 es = ES_NOFIX;
00289 pathset_h(hall, x0, w, w);
00290 }
00291 if (hall[z].d == hall[y].bounds-hall[z].bounds) {
00292 pathset_h(hall, hall[y].h, j+1, y);
00293 hall[y].h = j+1;
00294 }
00295 }
00296
00297 return es;
00298 }
00299
00300 #undef GECODE_INT_MINSORTED
00301 #undef GECODE_INT_MAXSORTED
00302
00303 template <class View>
00304 ExecStatus
00305 Bnd<View>::propagate(Space* home, ModEventDelta med) {
00306 assert(x.size() > 1);
00307
00308 if (View::me(med) == ME_INT_VAL) {
00309 ExecStatus es = prop_val<View,false>(home,y);
00310 GECODE_ES_CHECK(es);
00311 if (y.size() < 2)
00312 return ES_SUBSUMED(this,home);
00313 if (es == ES_FIX)
00314 return ES_FIX_PARTIAL(this,View::med(ME_INT_BND));
00315 }
00316
00317 if (y.size() == 2)
00318 GECODE_REWRITE(this,Rel::Nq<View>::post(home,y[0],y[1]));
00319
00320 ExecStatus es = prop_bnd<View>(home,x);
00321
00322 GECODE_ES_CHECK(es);
00323
00324 const int n = x.size();
00325
00326 if ((n > 2*y.size()) && (n > 6)) {
00327
00328 MinInc<View> min_inc;
00329 Support::insertion<View,MinInc<View> >(&x[0], n, min_inc);
00330 int i = 0;
00331 int j = 0;
00332 int max = x[0].max()-1;
00333 while (i < n-1) {
00334 if (!x[i].assigned() ||
00335 (x[i].val() <= max) || (x[i].val() > x[i+1].min())) {
00336
00337 max = std::max(max,x[i].max());
00338 x[j++]=x[i];
00339 }
00340 i++;
00341 }
00342 if (!x[i].assigned() || (x[i].val() <= max))
00343 x[j++]=x[i];
00344 x.size(j);
00345 }
00346
00347 if (x.size() < 2)
00348 return ES_SUBSUMED(this,home);
00349
00350 if (x.size() == 2)
00351 GECODE_REWRITE(this,Rel::Nq<View>::post(home,x[0],x[1]));
00352
00353 return es;
00354 }
00355
00356 template <class View>
00357 ExecStatus
00358 Bnd<View>::post(Space* home, ViewArray<View>& x){
00359 if (x.size() == 2)
00360 return Rel::Nq<View>::post(home,x[0],x[1]);
00361 if (x.size() > 2)
00362 (void) new (home) Bnd<View>(home,x);
00363 return ES_OK;
00364 }
00365
00366 template <class View>
00367 void
00368 Bnd<View>::post(Space* home, Reflection::VarMap& vars,
00369 const Reflection::ActorSpec& spec) {
00370 spec.checkArity(1);
00371 ViewArray<View> x(home, vars, spec[0]);
00372 (void) new (home) Bnd<View>(home, x);
00373 }
00374
00375 }}}
00376
00377
00378