activity.hpp /usr/include/gecode/kernel.hh Gecode::Activity Gecode::Activity::Recorder Gecode::Activity::Storage Gecode::Activity::Recorder Gecode::Activity::Recorder::Idx Gecode /*-*-mode:C++;c-basic-offset:2;indent-tabs-mode:nil-*-*/ /* *Mainauthors: *ChristianSchulte<schulte@gecode.org> * *Copyright: *ChristianSchulte,2012 * *Lastmodified: *$Date:2013-07-2700:49:48+0200(Sat,27Jul2013)$by$Author:tack$ *$Revision:13949$ * *ThisfileispartofGecode,thegenericconstraint *developmentenvironment: *http://www.gecode.org * *Permissionisherebygranted,freeofcharge,toanypersonobtaining *acopyofthissoftwareandassociateddocumentationfiles(the *"Software"),todealintheSoftwarewithoutrestriction,including *withoutlimitationtherightstouse,copy,modify,merge,publish, *distribute,sublicense,and/orsellcopiesoftheSoftware,andto *permitpersonstowhomtheSoftwareisfurnishedtodoso,subjectto *thefollowingconditions: * *Theabovecopyrightnoticeandthispermissionnoticeshallbe *includedinallcopiesorsubstantialportionsoftheSoftware. * *THESOFTWAREISPROVIDED"ASIS",WITHOUTWARRANTYOFANYKIND, *EXPRESSORIMPLIED,INCLUDINGBUTNOTLIMITEDTOTHEWARRANTIESOF *MERCHANTABILITY,FITNESSFORAPARTICULARPURPOSEAND *NONINFRINGEMENT.INNOEVENTSHALLTHEAUTHORSORCOPYRIGHTHOLDERSBE *LIABLEFORANYCLAIM,DAMAGESOROTHERLIABILITY,WHETHERINANACTION *OFCONTRACT,TORTOROTHERWISE,ARISINGFROM,OUTOFORINCONNECTION *WITHTHESOFTWAREORTHEUSEOROTHERDEALINGSINTHESOFTWARE. * */ namespaceGecode{ classActivity{ protected: template<classView> classRecorder; classStorage{ public: Support::Mutexm; unsignedintuse_cnt; double*a; intn; doubled; template<classView> Storage(Homehome,ViewArray<View>&x,doubled, typenameBranchTraits<typename View::VarType>::Meritbm); ~Storage(void); staticvoid*operatornew(size_ts); staticvoidoperatordelete(void*p); }; Storage*storage; voidupdate(inti); voiddecay(inti); voidacquire(void); voidrelease(void); public: Activity(void); GECODE_KERNEL_EXPORT Activity(constActivity&a); GECODE_KERNEL_EXPORT Activity&operator =(constActivity&a); template<classView> Activity(Homehome,ViewArray<View>&x,doubled, typenameBranchTraits<typename View::VarType>::Meritbm); template<classView> voidinit(Homehome,ViewArray<View>&x,doubled, typenameBranchTraits<typename View::VarType>::Meritbm); boolinitialized(void)const; GECODE_KERNEL_EXPORT voidset(Space&home,doublea=0.0); GECODE_KERNEL_EXPORTstaticconstActivitydef; GECODE_KERNEL_EXPORT voidupdate(Space&home,boolshare,Activity&a); GECODE_KERNEL_EXPORT ~Activity(void); doubleoperator [](inti)const; intsize(void)const; GECODE_KERNEL_EXPORT voiddecay(Space&home,doubled); GECODE_KERNEL_EXPORT doubledecay(constSpace&home)const; }; template<classView> classActivity::Recorder:publicNaryPropagator<View,PC_GEN_NONE>{ protected: usingNaryPropagator<View,PC_GEN_NONE>::x; classIdx:publicAdvisor{ protected: int_info; public: Idx(Space&home,Propagator&p,Council<Idx>&c,inti); Idx(Space&home,boolshare,Idx&a); voidmark(void); voidunmark(void); boolmarked(void)const; intidx(void)const; }; Activitya; Council<Idx>c; Recorder(Space&home,boolshare,Recorder<View>&p); public: Recorder(Homehome,ViewArray<View>&x,Activity&a); virtualPropagator*copy(Space&home,boolshare); virtualPropCostcost(constSpace&home,constModEventDelta&med)const; virtualExecStatusadvise(Space&home,Advisor&a,constDelta&d); virtualExecStatuspropagate(Space&home,constModEventDelta&med); virtualsize_tdispose(Space&home); staticExecStatuspost(Homehome,ViewArray<View>&x,Activity&a); }; template<classChar,classTraits> std::basic_ostream<Char,Traits>& operator<<(std::basic_ostream<Char,Traits>&os, constActivity&a); /* *Advisorforactivityrecorder * */ template<classView> forceinline Activity::Recorder<View>::Idx::Idx(Space&home,Propagator&p, Council<Idx>&c,inti) :Advisor(home,p,c),_info(i<<1){} template<classView> forceinline Activity::Recorder<View>::Idx::Idx(Space&home,boolshare,Idx&a) :Advisor(home,share,a),_info(a._info){ } template<classView> forceinlinevoid Activity::Recorder<View>::Idx::mark(void){ _info|=1; } template<classView> forceinlinevoid Activity::Recorder<View>::Idx::unmark(void){ _info&=~1; } template<classView> forceinlinebool Activity::Recorder<View>::Idx::marked(void)const{ return(_info&1)!=0; } template<classView> forceinlineint Activity::Recorder<View>::Idx::idx(void)const{ return_info>>1; } /* *Postingofactivityrecorderpropagator * */ template<classView> forceinline Activity::Recorder<View>::Recorder(Homehome,ViewArray<View>&x, Activity&a0) :NaryPropagator<View,PC_GEN_NONE>(home,x),a(a0),c(home){ home.notice(*this,AP_DISPOSE); for(inti=x.size();i--;) if(!x[i].assigned()) x[i].subscribe(home,*new(home)Idx(home,*this,c,i)); } template<classView> forceinlineExecStatus Activity::Recorder<View>::post(Homehome,ViewArray<View>&x, Activity&a){ (void)new(home)Recorder<View>(home,x,a); returnES_OK; } /* *Activityvaluestorage * */ forceinlinevoid* Activity::Storage::operatornew(size_ts){ returnGecode::heap.ralloc(s); } forceinlinevoid Activity::Storage::operatordelete(void*p){ Gecode::heap.rfree(p); } template<classView> forceinline Activity::Storage::Storage(Homehome,ViewArray<View>&x,doubled0, typename BranchTraits<typename View::VarType>::Meritbm) :use_cnt(1),a(heap.alloc<double>(x.size())),n(x.size()),d(d0){ if(bm!=NULL) for(inti=n;i--;){ typenameView::VarTypexi(x[i].varimp()); a[i]=bm(home,xi,i); } else for(inti=n;i--;) a[i]=0.0; } forceinline Activity::Storage::~Storage(void){ heap.free<double>(a,n); } /* *Activity * */ forceinlinevoid Activity::update(inti){ assert(storage!=NULL); assert((i>=0)&&(i<storage->n)); storage->a[i]+=1.0; } forceinlinevoid Activity::decay(inti){ assert(storage!=NULL); assert((i>=0)&&(i<storage->n)); storage->a[i]*=storage->d; } forceinlinedouble Activity::operator [](inti)const{ assert(storage!=NULL); assert((i>=0)&&(i<storage->n)); returnstorage->a[i]; } forceinlineint Activity::size(void)const{ returnstorage->n; } forceinlinevoid Activity::acquire(void){ storage->m.acquire(); } forceinlinevoid Activity::release(void){ storage->m.release(); } forceinline Activity::Activity(void):storage(NULL){} forceinlinebool Activity::initialized(void)const{ returnstorage!=NULL; } template<classView> forceinline Activity::Activity(Homehome,ViewArray<View>&x,doubled, typenameBranchTraits<typename View::VarType>::Meritbm){ assert(storage==NULL); storage=newStorage(home,x,d,bm); (void)Recorder<View>::post(home,x,*this); } template<classView> forceinlinevoid Activity::init(Homehome,ViewArray<View>&x,doubled, typenameBranchTraits<typenameView::VarType>::Meritbm){ assert(storage==NULL); storage=newStorage(home,x,d,bm); (void)Recorder<View>::post(home,x,*this); } template<classChar,classTraits> std::basic_ostream<Char,Traits>& operator<<(std::basic_ostream<Char,Traits>&os, constActivity&a){ std::basic_ostringstream<Char,Traits>s; s.copyfmt(os);s.width(0); s<<'{'; if(a.size()>0){ s<<a[0]; for(inti=1;i<a.size();i++) s<<","<<a[i]; } s<<'}'; returnos<<s.str(); } /* *Propagationforactivityrecorder * */ template<classView> forceinline Activity::Recorder<View>::Recorder(Space&home,boolshare, Recorder<View>&p) :NaryPropagator<View,PC_GEN_NONE>(home,share,p){ a.update(home,share,p.a); c.update(home,share,p.c); } template<classView> Propagator* Activity::Recorder<View>::copy(Space&home,boolshare){ returnnew(home)Recorder<View>(home,share,*this); } template<classView> inlinesize_t Activity::Recorder<View>::dispose(Space&home){ //Deleteaccesstoactivityinformation home.ignore(*this,AP_DISPOSE); a.~Activity(); //Cancelremainingadvisors for(Advisors<Idx>as(c);as();++as) x[as.advisor().idx()].cancel(home,as.advisor()); c.dispose(home); (void)NaryPropagator<View,PC_GEN_NONE>::dispose(home); returnsizeof(*this); } template<classView> PropCost Activity::Recorder<View>::cost(constSpace&,constModEventDelta&)const{ returnPropCost::crazy(PropCost::HI,1000); } template<classView> ExecStatus Activity::Recorder<View>::advise(Space&,Advisor&a,constDelta&){ static_cast<Idx&>(a).mark(); returnES_NOFIX; } template<classView> ExecStatus Activity::Recorder<View>::propagate(Space&home,constModEventDelta&){ //Lockactivityinformation a.acquire(); for(Advisors<Idx>as(c);as();++as){ inti=as.advisor().idx(); if(as.advisor().marked()){ as.advisor().unmark(); a.update(i); if(x[i].assigned()) as.advisor().dispose(home,c); }else{ assert(!x[i].assigned()); a.decay(i); } } a.release(); returnc.empty()?home.ES_SUBSUMED(*this):ES_FIX; } } //STATISTICS:kernel-branch