代码如下:
#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已经不能再进行修改。