gecode中的idx recorder分析
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了gecode中的idx recorder分析相关的知识,希望对你有一定的参考价值。
1、定义,只有一个变量info,gecode中的常用技法,将多种信息存在一个变量中, info最后一位作为mask标识,其它位作为id标识。
/// Advisor with index and change information class Idx : public Advisor { protected: /// Index and mark information int _info; public: /// Constructor for creation Idx(Space& home, Propagator& p, Council<Idx>& c, int i); /// Constructor for cloning \a a Idx(Space& home, bool share, Idx& a); /// Mark advisor as modified void mark(void); /// Mark advisor as unmodified void unmark(void); /// Whether advisor‘s view has been marked bool marked(void) const; /// Get index of view int idx(void) const; };
2、实现
/* * Advisor for activity recorder * */ template<class View> forceinline Activity::Recorder<View>::Idx::Idx(Space& home, Propagator& p, Council<Idx>& c, int i) : Advisor(home,p,c), _info(i << 1) {} template<class View> forceinline Activity::Recorder<View>::Idx::Idx(Space& home, bool share, Idx& a) : Advisor(home,share,a), _info(a._info) { } template<class View> forceinline void Activity::Recorder<View>::Idx::mark(void) { _info |= 1; } template<class View> forceinline void Activity::Recorder<View>::Idx::unmark(void) { _info &= ~1; } template<class View> forceinline bool Activity::Recorder<View>::Idx::marked(void) const { return (_info & 1) != 0; } template<class View> forceinline int Activity::Recorder<View>::Idx::idx(void) const { return _info >> 1; }
这个类从advisor继承,又进行这样的操作,是为了和recorder一起使用,当然也可以使用在其它地方,根据标记进行相应操作。 这里的使用方式值得借鉴,果然还是要从代码来入手,show me the code, 文档之类的始终太皮毛
/* * Posting of activity recorder propagator * */ template<class View> forceinline Activity::Recorder<View>::Recorder(Home home, ViewArray<View>& x, Activity& a0) : NaryPropagator<View,PC_GEN_NONE>(home,x), a(a0), c(home) { home.notice(*this,AP_DISPOSE); for (int i=x.size(); i--; ) if (!x[i].assigned()) x[i].subscribe(home,*new (home) Idx(home,*this,c,i)); } template<class View> forceinline ExecStatus Activity::Recorder<View>::post(Home home, ViewArray<View>& x, Activity& a) { (void) new (home) Recorder<View>(home,x,a); return ES_OK; } /* * Propagation for activity recorder * */ template<class View> forceinline Activity::Recorder<View>::Recorder(Space& home, bool share, Recorder<View>& p) : NaryPropagator<View,PC_GEN_NONE>(home,share,p) { a.update(home, share, p.a); c.update(home, share, p.c); } template<class View> Propagator* Activity::Recorder<View>::copy(Space& home, bool share) { return new (home) Recorder<View>(home, share, *this); } template<class View> inline size_t Activity::Recorder<View>::dispose(Space& home) { // Delete access to activity information home.ignore(*this,AP_DISPOSE); a.~Activity(); // Cancel remaining advisors 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); return sizeof(*this); } template<class View> PropCost Activity::Recorder<View>::cost(const Space&, const ModEventDelta&) const { return PropCost::record(); } template<class View> void Activity::Recorder<View>::reschedule(Space& home) { View::schedule(home,*this,ME_GEN_ASSIGNED); } template<class View> ExecStatus Activity::Recorder<View>::advise(Space&, Advisor& a, const Delta&) { static_cast<Idx&>(a).mark(); return ES_NOFIX; } template<class View> ExecStatus Activity::Recorder<View>::propagate(Space& home, const ModEventDelta&) { // Lock activity information a.acquire(); for (Advisors<Idx> as(c); as(); ++as) { int i = 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(); return c.empty() ? home.ES_SUBSUMED(*this) : ES_FIX; }
以上是关于gecode中的idx recorder分析的主要内容,如果未能解决你的问题,请参考以下文章