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 {
00039
00044 class Activity {
00045 protected:
00046 template<class View>
00047 class Recorder;
00049 class Storage {
00050 public:
00052 Support::Mutex m;
00054 unsigned int use_cnt;
00056 double* a;
00058 int n;
00060 double d;
00062 template<class View>
00063 Storage(Home home, ViewArray<View>& x, double d,
00064 typename BranchTraits<typename View::VarType>::Merit bm);
00066 ~Storage(void);
00068 static void* operator new(size_t s);
00070 static void operator delete(void* p);
00071 };
00072
00074 Storage* storage;
00076 void update(int i);
00078 void decay(int i);
00080 void acquire(void);
00082 void release(void);
00083 public:
00085
00086
00093 Activity(void);
00095 GECODE_KERNEL_EXPORT
00096 Activity(const Activity& a);
00098 GECODE_KERNEL_EXPORT
00099 Activity& operator =(const Activity& a);
00101 template<class View>
00102 Activity(Home home, ViewArray<View>& x, double d,
00103 typename BranchTraits<typename View::VarType>::Merit bm);
00105 template<class View>
00106 void init(Home home, ViewArray<View>& x, double d,
00107 typename BranchTraits<typename View::VarType>::Merit bm);
00109 bool initialized(void) const;
00111 GECODE_KERNEL_EXPORT
00112 void set(Space& home, double a=0.0);
00114 GECODE_KERNEL_EXPORT static const Activity def;
00116
00118
00119
00120 GECODE_KERNEL_EXPORT
00121 void update(Space& home, bool share, Activity& a);
00123 GECODE_KERNEL_EXPORT
00124 ~Activity(void);
00126
00128
00129
00130 double operator [](int i) const;
00132 int size(void) const;
00134
00136
00137
00138 GECODE_KERNEL_EXPORT
00139 void decay(Space& home, double d);
00141 GECODE_KERNEL_EXPORT
00142 double decay(const Space& home) const;
00144 };
00145
00147 template<class View>
00148 class Activity::Recorder : public NaryPropagator<View,PC_GEN_NONE> {
00149 protected:
00150 using NaryPropagator<View,PC_GEN_NONE>::x;
00152 class Idx : public Advisor {
00153 protected:
00155 int _info;
00156 public:
00158 Idx(Space& home, Propagator& p, Council<Idx>& c, int i);
00160 Idx(Space& home, bool share, Idx& a);
00162 void mark(void);
00164 void unmark(void);
00166 bool marked(void) const;
00168 int idx(void) const;
00169 };
00171 Activity a;
00173 Council<Idx> c;
00175 Recorder(Space& home, bool share, Recorder<View>& p);
00176 public:
00178 Recorder(Home home, ViewArray<View>& x, Activity& a);
00180 virtual Propagator* copy(Space& home, bool share);
00182 virtual PropCost cost(const Space& home, const ModEventDelta& med) const;
00184 virtual ExecStatus advise(Space& home, Advisor& a, const Delta& d);
00186 virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
00188 virtual size_t dispose(Space& home);
00190 static ExecStatus post(Home home, ViewArray<View>& x, Activity& a);
00191 };
00192
00197 template<class Char, class Traits>
00198 std::basic_ostream<Char,Traits>&
00199 operator <<(std::basic_ostream<Char,Traits>& os,
00200 const Activity& a);
00201
00202
00203
00204
00205
00206
00207 template<class View>
00208 forceinline
00209 Activity::Recorder<View>::Idx::Idx(Space& home, Propagator& p,
00210 Council<Idx>& c, int i)
00211 : Advisor(home,p,c), _info(i << 1) {}
00212 template<class View>
00213 forceinline
00214 Activity::Recorder<View>::Idx::Idx(Space& home, bool share, Idx& a)
00215 : Advisor(home,share,a), _info(a._info) {
00216 }
00217 template<class View>
00218 forceinline void
00219 Activity::Recorder<View>::Idx::mark(void) {
00220 _info |= 1;
00221 }
00222 template<class View>
00223 forceinline void
00224 Activity::Recorder<View>::Idx::unmark(void) {
00225 _info &= ~1;
00226 }
00227 template<class View>
00228 forceinline bool
00229 Activity::Recorder<View>::Idx::marked(void) const {
00230 return (_info & 1) != 0;
00231 }
00232 template<class View>
00233 forceinline int
00234 Activity::Recorder<View>::Idx::idx(void) const {
00235 return _info >> 1;
00236 }
00237
00238
00239
00240
00241
00242
00243
00244 template<class View>
00245 forceinline
00246 Activity::Recorder<View>::Recorder(Home home, ViewArray<View>& x,
00247 Activity& a0)
00248 : NaryPropagator<View,PC_GEN_NONE>(home,x), a(a0), c(home) {
00249 home.notice(*this,AP_DISPOSE);
00250 for (int i=x.size(); i--; )
00251 if (!x[i].assigned())
00252 x[i].subscribe(home,*new (home) Idx(home,*this,c,i));
00253 }
00254
00255 template<class View>
00256 forceinline ExecStatus
00257 Activity::Recorder<View>::post(Home home, ViewArray<View>& x,
00258 Activity& a) {
00259 (void) new (home) Recorder<View>(home,x,a);
00260 return ES_OK;
00261 }
00262
00263
00264
00265
00266
00267
00268 forceinline void*
00269 Activity::Storage::operator new(size_t s) {
00270 return Gecode::heap.ralloc(s);
00271 }
00272 forceinline void
00273 Activity::Storage::operator delete(void* p) {
00274 Gecode::heap.rfree(p);
00275 }
00276 template<class View>
00277 forceinline
00278 Activity::Storage::Storage(Home home, ViewArray<View>& x, double d0,
00279 typename
00280 BranchTraits<typename View::VarType>::Merit bm)
00281 : use_cnt(1), a(heap.alloc<double>(x.size())), n(x.size()), d(d0) {
00282 if (bm != NULL)
00283 for (int i=n; i--; ) {
00284 typename View::VarType xi(x[i].varimp());
00285 a[i] = bm(home,xi,i);
00286 }
00287 else
00288 for (int i=n; i--; )
00289 a[i] = 0.0;
00290 }
00291 forceinline
00292 Activity::Storage::~Storage(void) {
00293 heap.free<double>(a,n);
00294 }
00295
00296
00297
00298
00299
00300
00301
00302 forceinline void
00303 Activity::update(int i) {
00304 assert(storage != NULL);
00305 assert((i >= 0) && (i < storage->n));
00306 storage->a[i] += 1.0;
00307 }
00308 forceinline void
00309 Activity::decay(int i) {
00310 assert(storage != NULL);
00311 assert((i >= 0) && (i < storage->n));
00312 storage->a[i] *= storage->d;
00313 }
00314 forceinline double
00315 Activity::operator [](int i) const {
00316 assert(storage != NULL);
00317 assert((i >= 0) && (i < storage->n));
00318 return storage->a[i];
00319 }
00320 forceinline int
00321 Activity::size(void) const {
00322 return storage->n;
00323 }
00324 forceinline void
00325 Activity::acquire(void) {
00326 storage->m.acquire();
00327 }
00328 forceinline void
00329 Activity::release(void) {
00330 storage->m.release();
00331 }
00332
00333
00334 forceinline
00335 Activity::Activity(void) : storage(NULL) {}
00336
00337 forceinline bool
00338 Activity::initialized(void) const {
00339 return storage != NULL;
00340 }
00341
00342 template<class View>
00343 forceinline
00344 Activity::Activity(Home home, ViewArray<View>& x, double d,
00345 typename BranchTraits<typename View::VarType>::Merit bm) {
00346 assert(storage == NULL);
00347 storage = new Storage(home,x,d,bm);
00348 (void) Recorder<View>::post(home,x,*this);
00349 }
00350 template<class View>
00351 forceinline void
00352 Activity::init(Home home, ViewArray<View>& x, double d,
00353 typename BranchTraits<typename View::VarType>::Merit bm) {
00354 assert(storage == NULL);
00355 storage = new Storage(home,x,d,bm);
00356 (void) Recorder<View>::post(home,x,*this);
00357 }
00358
00359 template<class Char, class Traits>
00360 std::basic_ostream<Char,Traits>&
00361 operator <<(std::basic_ostream<Char,Traits>& os,
00362 const Activity& a) {
00363 std::basic_ostringstream<Char,Traits> s;
00364 s.copyfmt(os); s.width(0);
00365 s << '{';
00366 if (a.size() > 0) {
00367 s << a[0];
00368 for (int i=1; i<a.size(); i++)
00369 s << ", " << a[i];
00370 }
00371 s << '}';
00372 return os << s.str();
00373 }
00374
00375
00376
00377
00378
00379
00380 template<class View>
00381 forceinline
00382 Activity::Recorder<View>::Recorder(Space& home, bool share,
00383 Recorder<View>& p)
00384 : NaryPropagator<View,PC_GEN_NONE>(home,share,p) {
00385 a.update(home, share, p.a);
00386 c.update(home, share, p.c);
00387 }
00388
00389 template<class View>
00390 Propagator*
00391 Activity::Recorder<View>::copy(Space& home, bool share) {
00392 return new (home) Recorder<View>(home, share, *this);
00393 }
00394
00395 template<class View>
00396 inline size_t
00397 Activity::Recorder<View>::dispose(Space& home) {
00398
00399 home.ignore(*this,AP_DISPOSE);
00400 a.~Activity();
00401
00402 for (Advisors<Idx> as(c); as(); ++as)
00403 x[as.advisor().idx()].cancel(home,as.advisor());
00404 c.dispose(home);
00405 (void) NaryPropagator<View,PC_GEN_NONE>::dispose(home);
00406 return sizeof(*this);
00407 }
00408
00409 template<class View>
00410 PropCost
00411 Activity::Recorder<View>::cost(const Space&, const ModEventDelta&) const {
00412 return PropCost::crazy(PropCost::HI,1000);
00413 }
00414
00415 template<class View>
00416 ExecStatus
00417 Activity::Recorder<View>::advise(Space&, Advisor& a, const Delta&) {
00418 static_cast<Idx&>(a).mark();
00419 return ES_NOFIX;
00420 }
00421
00422 template<class View>
00423 ExecStatus
00424 Activity::Recorder<View>::propagate(Space& home, const ModEventDelta&) {
00425
00426 a.acquire();
00427 for (Advisors<Idx> as(c); as(); ++as) {
00428 int i = as.advisor().idx();
00429 if (as.advisor().marked()) {
00430 as.advisor().unmark();
00431 a.update(i);
00432 if (x[i].assigned())
00433 as.advisor().dispose(home,c);
00434 } else {
00435 assert(!x[i].assigned());
00436 a.decay(i);
00437 }
00438 }
00439 a.release();
00440 return c.empty() ? home.ES_SUBSUMED(*this) : ES_FIX;
00441 }
00442
00443 }
00444
00445