gecode中自定義brancher
阿新 • • 發佈:2017-09-03
size 方式 val mit share pro clu assign rtu
實際應用中,往往要比官方的示例復雜很多,這裏對變量的選擇等往往需要以自定義的方式進行選擇,這個時候就需要自定義brancher,相關註釋在代碼中
#include <gecode/int.hh> using namespace Gecode; class NoneMin : public Brancher { protected: ViewArray<Int::IntView> x; // choice definition class PosVal : public Choice { public: int pos; int val; PosVal(const NoneMin& b, int p, int v) : Choice(b,2), pos(p), val(v) {} virtual size_t size(void) const { return sizeof(*this); } virtual void archive(Archive& e) const { Choice::archive(e); e << pos << val; } }; public: NoneMin(Home home, ViewArray<Int::IntView>& x0) : Brancher(home), x(x0) {} static void post(Home home, ViewArray<Int::IntView>& x) { (void) new (home) NoneMin(home,x); } virtual size_t dispose(Space& home) { (void) Brancher::dispose(home); return sizeof(*this); } NoneMin(Space& home, bool share, NoneMin& b) : Brancher(home,share,b) { x.update(home,share,b.x); } virtual Brancher* copy(Space& home, bool share) { return new (home) NoneMin(home,share,*this); } // status 選擇某個變量,有時有些變量需要有優處理,這時可以在這個地方選擇virtual bool status(const Space& home) const { for (int i=0; i<x.size(); i++) if (!x[i].assigned()) return true; return false; } // choice 通過這個函數取得choice virtual Choice* choice(Space& home) { for (int i=0; true; i++) if (!x[i].assigned()) return new PosVal(*this,i,x[i].min()); GECODE_NEVER; return NULL; } virtual Choice* choice(const Space&, Archive& e) { int pos, val; e >> pos >> val; return new PosVal(*this, pos, val); } // commit virtual ExecStatus commit(Space& home, const Choice& c, unsigned int a) { const PosVal& pv = static_cast<const PosVal&>(c); int pos=pv.pos, val=pv.val; if (a == 0) //這裏對應的一個節點的兩個分支,左邊的節點為付值,右邊的節點為排除。 return me_failed(x[pos].eq(home,val)) ? ES_FAILED : ES_OK; else return me_failed(x[pos].nq(home,val)) ? ES_FAILED : ES_OK; } // print virtual void print(const Space& home, const Choice& c, unsigned int a, std::ostream& o) const { const PosVal& pv = static_cast<const PosVal&>(c); int pos=pv.pos, val=pv.val; if (a == 0) o << "x[" << pos << "] = " << val; else o << "x[" << pos << "] != " << val; } }; void nonemin(Home home, const IntVarArgs& x) { if (home.failed()) return; ViewArray<Int::IntView> y(home,x); NoneMin::post(home,y); }
commit函數在worker中被調用
void Space::_commit(const Choice& c, unsigned int a) { if (a >= c.alternatives()) throw SpaceIllegalAlternative("Space::commit"); if (failed()) return; if (Brancher* b = brancher(c.bid)) { // There is a matching brancher pc.p.ei.brancher(*b); ExecStatus es = b->commit(*this,c,a); pc.p.ei.other(); if (es == ES_FAILED) fail(); } else { // There is no matching brancher! throw SpaceNoBrancher("Space::commit"); } }
gecode中自定義brancher