gecode less 示例分析
代码如下:
#include <gecode/int.hh> using namespace Gecode; class Less : public Propagator { protected: Int::IntView x0, x1; public: // posting Less(Space& home, Int::IntView y0, Int::IntView y1) : Propagator(home), x0(y0), x1(y1) { x0.subscribe(home,*this,Int::PC_INT_DOM); x1.subscribe(home,*this,Int::PC_INT_DOM); } static ExecStatus post(Space& home, Int::IntView x0, Int::IntView x1) { (void) new (home) Less(home,x0,x1); return ES_OK; } // disposal virtual size_t dispose(Space& home) { x0.cancel(home,*this,Int::PC_INT_DOM); x1.cancel(home,*this,Int::PC_INT_DOM); (void) Propagator::dispose(home); return sizeof(*this); } // copying Less(Space& home, bool share, Less& p) : Propagator(home,share,p) { x0.update(home,share,p.x0); x1.update(home,share,p.x1); } virtual Propagator* copy(Space& home, bool share) { return new (home) Less(home,share,*this); } // cost computation virtual PropCost cost(const Space&, const ModEventDelta&) const { return PropCost::binary(PropCost::LO); } // re-scheduling virtual void reschedule(Space& home) { x0.reschedule(home,*this,Int::PC_INT_DOM); x1.reschedule(home,*this,Int::PC_INT_DOM); } // propagation virtual ExecStatus propagate(Space& home, const ModEventDelta&) { if (x0.le(home,x1.max()) == Int::ME_INT_FAILED) return ES_FAILED; if (x1.gr(home,x0.min()) == Int::ME_INT_FAILED) return ES_FAILED; if (x0.assigned() && x1.assigned()) return home.ES_SUBSUMED(*this); else return ES_NOFIX; } }; void less(Space& home, IntVar x0, IntVar x1) { // constraint post function Int::IntView y0(x0), y1(x1); if (Less::post(home,y0,y1) != ES_OK) home.fail(); }
1、声明两个变量
Int::IntView x0, x1;
2、订阅事件,也就是说在变量发生改变,如dom,值等发生改变的时候调用 propagate 函数。
x0.subscribe(home,*this,Int::PC_INT_DOM); x1.subscribe(home,*this,Int::PC_INT_DOM);
reschedue的时候需要重新订阅。
virtual void reschedule(Space& home) { x0.reschedule(home,*this,Int::PC_INT_DOM); x1.reschedule(home,*this,Int::PC_INT_DOM); }
dipose的时候取消订阅
virtual size_t dispose(Space& home) { x0.cancel(home,*this,Int::PC_INT_DOM); x1.cancel(home,*this,Int::PC_INT_DOM); (void) Propagator::dispose(home); return sizeof(*this); }
3、处理具体业务逻辑。
// propagation virtual ExecStatus propagate(Space& home, const ModEventDelta&) { if (x0.le(home,x1.max()) == Int::ME_INT_FAILED) return ES_FAILED; if (x1.gr(home,x0.min()) == Int::ME_INT_FAILED) return ES_FAILED; if (x0.assigned() && x1.assigned()) return home.ES_SUBSUMED(*this); else return ES_NOFIX; }
说明,这里只是检查了是否完成,返回的都是ES_NOFIX, 没有进行FIX状态检查,FIX意思是说x1 、x2已经不能再进行修改。