Generated on Fri Mar 20 15:55:58 2015 for Gecode by doxygen 1.6.3

activity.hpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2012
00008  *
00009  *  Last modified:
00010  *     $Date: 2013-07-27 00:49:48 +0200 (Sat, 27 Jul 2013) $ by $Author: tack $
00011  *     $Revision: 13949 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *  Permission is hereby granted, free of charge, to any person obtaining
00018  *  a copy of this software and associated documentation files (the
00019  *  "Software"), to deal in the Software without restriction, including
00020  *  without limitation the rights to use, copy, modify, merge, publish,
00021  *  distribute, sublicense, and/or sell copies of the Software, and to
00022  *  permit persons to whom the Software is furnished to do so, subject to
00023  *  the following conditions:
00024  *
00025  *  The above copyright notice and this permission notice shall be
00026  *  included in all copies or substantial portions of the Software.
00027  *
00028  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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    * Advisor for activity recorder
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    * Posting of activity recorder propagator
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    * Activity value storage
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    * Activity
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    * Propagation for activity recorder
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     // Delete access to activity information
00399     home.ignore(*this,AP_DISPOSE);
00400     a.~Activity();
00401     // Cancel remaining advisors
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     // Lock activity information
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 // STATISTICS: kernel-branch