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/int/bin-packing.hh>
00039
00040 namespace Gecode { namespace Int { namespace BinPacking {
00041
00042
00043
00044
00045
00046
00047 PropCost
00048 Pack::cost(const Space&, const ModEventDelta&) const {
00049 return PropCost::quadratic(PropCost::HI,bs.size());
00050 }
00051
00052 Actor*
00053 Pack::copy(Space& home, bool share) {
00054 return new (home) Pack(home,share,*this);
00055 }
00056
00058 class TellCache {
00059 protected:
00061 int* _nq;
00063 int _n_nq;
00065 int _eq;
00066 public:
00068 TellCache(Region& region, int m);
00070 void nq(int j);
00072 void eq(int j);
00074 ExecStatus tell(Space& home, IntView x);
00075 };
00076
00077 forceinline
00078 TellCache::TellCache(Region& region, int m)
00079 : _nq(region.alloc<int>(m)), _n_nq(0), _eq(-1) {}
00080 forceinline void
00081 TellCache::nq(int j) {
00082 _nq[_n_nq++] = j;
00083 }
00084 forceinline void
00085 TellCache::eq(int j) {
00086
00087 if (_eq == -1)
00088 _eq = j;
00089 else
00090 _eq = -2;
00091 }
00092 ExecStatus
00093 TellCache::tell(Space& home, IntView x) {
00094 if (_eq == -2) {
00095 return ES_FAILED;
00096 } else if (_eq >= 0) {
00097 GECODE_ME_CHECK(x.eq(home,_eq));
00098 }
00099 Iter::Values::Array nqi(_nq, _n_nq);
00100 GECODE_ME_CHECK(x.minus_v(home, nqi));
00101 _n_nq=0; _eq=-1;
00102 return ES_OK;
00103 }
00104
00105
00106
00107
00108
00109
00110 ExecStatus
00111 Pack::propagate(Space& home, const ModEventDelta& med) {
00112
00113 int n = bs.size();
00114
00115 int m = l.size();
00116
00117 {
00118 Region region(home);
00119
00120
00121 int* s = region.alloc<int>(m);
00122
00123 for (int j=m; j--; )
00124 s[j] = 0;
00125
00126
00127 if (OffsetView::me(med) == ME_INT_VAL) {
00128
00129 int k=0;
00130 for (int i=0; i<n; i++)
00131 if (bs[i].assigned()) {
00132 int j = bs[i].bin().val();
00133 l[j].offset(l[j].offset() - bs[i].size());
00134 t -= bs[i].size();
00135 } else {
00136 for (ViewValues<IntView> j(bs[i].bin()); j(); ++j)
00137 s[j.val()] += bs[i].size();
00138 bs[k++] = bs[i];
00139 }
00140 n=k; bs.size(n);
00141 } else {
00142 for (int i=n; i--; ) {
00143 assert(!bs[i].assigned());
00144 for (ViewValues<IntView> j(bs[i].bin()); j(); ++j)
00145 s[j.val()] += bs[i].size();
00146 }
00147 }
00148
00149
00150 int min = t, max = t;
00151 for (int j=m; j--; ) {
00152 GECODE_ME_CHECK(l[j].gq(home,0));
00153 GECODE_ME_CHECK(l[j].lq(home,s[j]));
00154 min -= l[j].max(); max -= l[j].min();
00155 }
00156
00157
00158 for (bool mod = true; mod; ) {
00159 mod = false; ModEvent me;
00160 for (int j=m; j--; ) {
00161 int lj_min = l[j].min();
00162 me = l[j].gq(home, min + l[j].max());
00163 if (me_failed(me))
00164 return ES_FAILED;
00165 if (me_modified(me)) {
00166 max += lj_min - l[j].min(); mod = true;
00167 }
00168 int lj_max = l[j].max();
00169 me = l[j].lq(home, max + l[j].min());
00170 if (me_failed(me))
00171 return ES_FAILED;
00172 if (me_modified(me)) {
00173 min += lj_max - l[j].max(); mod = true;
00174 }
00175 }
00176 }
00177
00178 if (n == 0) {
00179 assert(l.assigned());
00180 return home.ES_SUBSUMED(*this);
00181 }
00182
00183
00184 {
00185 TellCache tc(region,m);
00186
00187 int k=0;
00188 for (int i=0; i<n; i++) {
00189 for (ViewValues<IntView> j(bs[i].bin()); j(); ++j) {
00190 if (bs[i].size() > l[j.val()].max())
00191 tc.nq(j.val());
00192 if (s[j.val()] - bs[i].size() < l[j.val()].min())
00193 tc.eq(j.val());
00194 }
00195 GECODE_ES_CHECK(tc.tell(home,bs[i].bin()));
00196
00197 if (bs[i].assigned()) {
00198 int j = bs[i].bin().val();
00199 l[j].offset(l[j].offset() - bs[i].size());
00200 t -= bs[i].size();
00201 } else {
00202 bs[k++] = bs[i];
00203 }
00204 }
00205 n=k; bs.size(n);
00206 }
00207
00208 }
00209
00210
00211
00212 if (IntView::me(modeventdelta()) != ME_INT_NONE)
00213 return ES_NOFIX;
00214
00215
00216 {
00217 Region region(home);
00218
00219
00220 SizeSetMinusOne* s = region.alloc<SizeSetMinusOne>(m);
00221
00222 for (int j=m; j--; )
00223 s[j] = SizeSetMinusOne(region,n);
00224
00225
00226 for (int i=0; i<n; i++) {
00227 assert(!bs[i].assigned());
00228 for (ViewValues<IntView> j(bs[i].bin()); j(); ++j)
00229 s[j.val()].add(bs[i].size());
00230 }
00231
00232 for (int j=m; j--; ) {
00233
00234 if (nosum(static_cast<SizeSet&>(s[j]), l[j].min(), l[j].max()))
00235 return ES_FAILED;
00236 int ap, bp;
00237
00238 if (nosum(static_cast<SizeSet&>(s[j]), l[j].min(), l[j].min(),
00239 ap, bp))
00240 GECODE_ME_CHECK(l[j].gq(home,bp));
00241
00242 if (nosum(static_cast<SizeSet&>(s[j]), l[j].max(), l[j].max(),
00243 ap, bp))
00244 GECODE_ME_CHECK(l[j].lq(home,ap));
00245 }
00246
00247 TellCache tc(region,m);
00248
00249 int k=0;
00250 for (int i=0; i<n; i++) {
00251 assert(!bs[i].assigned());
00252 for (ViewValues<IntView> j(bs[i].bin()); j(); ++j) {
00253
00254 s[j.val()].minus(bs[i].size());
00255
00256 if (nosum(s[j.val()],
00257 l[j.val()].min() - bs[i].size(),
00258 l[j.val()].max() - bs[i].size()))
00259 tc.nq(j.val());
00260
00261 if (nosum(s[j.val()], l[j.val()].min(), l[j.val()].max()))
00262 tc.eq(j.val());
00263 }
00264 GECODE_ES_CHECK(tc.tell(home,bs[i].bin()));
00265 if (bs[i].assigned()) {
00266 int j = bs[i].bin().val();
00267 l[j].offset(l[j].offset() - bs[i].size());
00268 t -= bs[i].size();
00269 } else {
00270 bs[k++] = bs[i];
00271 }
00272 }
00273 n=k; bs.size(n);
00274 }
00275
00276
00277 if (n > 0) {
00278 Region region(home);
00279
00280
00281
00282 int c = bs[0].size();
00283 for (int j=m; j--; )
00284 c = std::max(c,l[j].max());
00285
00286
00287 int* n_s = region.alloc<int>(c+1);
00288
00289 for (int i=c+1; i--; )
00290 n_s[i] = 0;
00291
00292
00293 for (int i=n; i--; )
00294 n_s[bs[i].size()]++;
00295
00296
00297 int nm = n;
00298
00299
00300 for (int j=m; j--; )
00301 if (l[j].max() < 0) {
00302 return ES_FAILED;
00303 } else if (c > l[j].max()) {
00304 n_s[c - l[j].max()]++; nm++;
00305 }
00306
00307
00308 int* s = region.alloc<int>(nm);
00309
00310
00311 {
00312 int k=0;
00313 for (int i=c+1; i--; )
00314 for (int n=n_s[i]; n--; )
00315 s[k++]=i;
00316 assert(k == nm);
00317 }
00318
00319
00320 int n1 = 0;
00321
00322 int n12 = 0;
00323
00324 int n3 = 0;
00325
00326 int f2 = 0;
00327
00328 int s3 = 0;
00329
00330
00331 for (; (n12 < nm) && (s[n12] > c/2); n12++)
00332 f2 += c - s[n12];
00333
00334
00335 for (n3 = n12; n3 < nm; n3++)
00336 s3 += s[n3];
00337
00338
00339 for (int k=0; k<=c/2; k++) {
00340
00341 for (; (n1 < nm) && (s[n1] > c-k); n1++)
00342 f2 -= c - s[n1];
00343 assert(n1 <= n12);
00344
00345 for (; (s[n3-1] < k) && (n3 > n12); n3--)
00346 s3 -= s[n3-1];
00347
00348 int o = (s3 > f2) ? ((s3 - f2 + c - 1) / c) : 0;
00349 if (n12 + o > m)
00350 return ES_FAILED;
00351 }
00352 }
00353
00354 return ES_NOFIX;
00355 }
00356
00357 ExecStatus
00358 Pack::post(Home home, ViewArray<OffsetView>& l, ViewArray<Item>& bs) {
00359 if (bs.size() == 0) {
00360
00361 for (int i=l.size(); i--; )
00362 GECODE_ME_CHECK(l[i].eq(home,0));
00363 return ES_OK;
00364 } else if (l.size() == 0) {
00365
00366 return ES_FAILED;
00367 } else {
00368 int s = 0;
00369
00370 for (int i=bs.size(); i--; ) {
00371 s += bs[i].size();
00372 GECODE_ME_CHECK(bs[i].bin().gq(home,0));
00373 GECODE_ME_CHECK(bs[i].bin().le(home,l.size()));
00374 }
00375
00376 for (int j=l.size(); j--; ) {
00377 GECODE_ME_CHECK(l[j].gq(home,0));
00378 GECODE_ME_CHECK(l[j].lq(home,s));
00379 }
00380 (void) new (home) Pack(home,l,bs);
00381 return ES_OK;
00382 }
00383 }
00384
00385 }}}
00386
00387
00388