标签:变量 void war 通过 space arch turn 调用 stat
实际应用中,往往要比官方的示例复杂很多,这里对变量的选择等往往需要以自定义的方式进行选择,这个时候就需要自定义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");
}
}
标签:变量 void war 通过 space arch turn 调用 stat
原文地址:http://www.cnblogs.com/crax/p/7470326.html