00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include <gecode/driver.hh>
00041 #include <gecode/int.hh>
00042 #include <gecode/minimodel.hh>
00043
00044 #if defined(GECODE_HAS_QT) && defined(GECODE_HAS_GIST)
00045 #include <QtGui>
00046 #endif
00047
00048 using namespace Gecode;
00049
00050
00059 class Warnsdorff : public Brancher {
00060 protected:
00062 ViewArray<Int::IntView> x;
00064 mutable int start;
00066 class Choice : public Gecode::Choice {
00067 public:
00069 int pos;
00071 int val;
00075 Choice(const Brancher& b, int pos0, int val0)
00076 : Gecode::Choice(b,2), pos(pos0), val(val0) {}
00078 virtual size_t size(void) const {
00079 return sizeof(Choice);
00080 }
00082 virtual void archive(Archive& e) const {
00083 Gecode::Choice::archive(e);
00084 e << pos << val;
00085 }
00086 };
00087
00089 Warnsdorff(Home home, ViewArray<Int::IntView>& xv)
00090 : Brancher(home), x(xv), start(0) {}
00092 Warnsdorff(Space& home, bool share, Warnsdorff& b)
00093 : Brancher(home, share, b), start(b.start) {
00094 x.update(home, share, b.x);
00095 }
00096 public:
00098 virtual bool status(const Space&) const {
00099
00100 for (int n=x.size(); n--; ) {
00101 if (!x[start].assigned())
00102 return true;
00103
00104 start = x[start].val();
00105 }
00106 return false;
00107 }
00109 virtual Gecode::Choice* choice(Space&) {
00110 Int::ViewValues<Int::IntView> iv(x[start]);
00111 int n = iv.val();
00112 unsigned int min = x[n].size();
00113 ++iv;
00114
00115 while (iv()) {
00116 if (x[iv.val()].size() < min) {
00117 n = iv.val();
00118 min = x[n].size();
00119 }
00120 ++iv;
00121 }
00122 return new Choice(*this, start, n);
00123 }
00125 virtual Choice* choice(const Space&, Archive& e) {
00126 int pos, val;
00127 e >> pos >> val;
00128 return new Choice(*this, pos, val);
00129 }
00131 virtual ExecStatus commit(Space& home, const Gecode::Choice& _c,
00132 unsigned int a) {
00133 const Choice& c = static_cast<const Choice&>(_c);
00134 if (a == 0)
00135 return me_failed(x[c.pos].eq(home, c.val)) ? ES_FAILED : ES_OK;
00136 else
00137 return me_failed(x[c.pos].nq(home, c.val)) ? ES_FAILED : ES_OK;
00138 }
00140 virtual Actor* copy(Space& home, bool share) {
00141 return new (home) Warnsdorff(home, share, *this);
00142 }
00144 static void post(Home home, const IntVarArgs& x) {
00145 ViewArray<Int::IntView> xv(home, x);
00146 (void) new (home) Warnsdorff(home, xv);
00147 }
00149 virtual size_t dispose(Space&) {
00150 return sizeof(*this);
00151 }
00152 };
00153
00154
00156 class Knights : public Script {
00157 public:
00159 const int n;
00161 IntVarArray succ;
00163 enum {
00164 PROP_REIFIED,
00165 PROP_CIRCUIT
00166 };
00168 enum {
00169 BRANCH_NAIVE,
00170 BRANCH_WARNSDORFF,
00171 };
00173 int f(int x, int y) const {
00174 return x + y*n;
00175 }
00177 int x(int f) const {
00178 return f % n;
00179 }
00181 int y(int f) const {
00182 return f / n;
00183 }
00185 IntSet neighbors(int i) {
00186 static const int moves[8][2] = {
00187 {-2,-1}, {-2,1}, {-1,-2}, {-1,2}, {1,-2}, {1,2}, {2,-1}, {2,1}
00188 };
00189 int nbs[8]; int n_nbs = 0;
00190 for (int m=0; m<8; m++) {
00191 int nx = x(i) + moves[m][0], ny = y(i) + moves[m][1];
00192 if ((nx >= 0) && (nx < n) && (ny >= 0) && (ny < n))
00193 nbs[n_nbs++] = f(nx,ny);
00194 }
00195 return IntSet(nbs,n_nbs);
00196 }
00198 Knights(const SizeOptions& opt)
00199 : n(opt.size()), succ(*this,n*n,0,n*n-1) {
00200 switch (opt.branching()) {
00201 case BRANCH_NAIVE:
00202 branch(*this, succ, INT_VAR_NONE, INT_VAL_MIN);
00203 break;
00204 case BRANCH_WARNSDORFF:
00205 Warnsdorff::post(*this, succ);
00206 break;
00207 }
00208 }
00210 Knights(bool share, Knights& s) : Script(share,s), n(s.n) {
00211 succ.update(*this, share, s.succ);
00212 }
00214 virtual void
00215 print(std::ostream& os) const {
00216 int* jump = new int[n*n];
00217 {
00218 int j=0;
00219 for (int i=0; i<n*n; i++) {
00220 jump[j]=i; j=succ[j].min();
00221 }
00222 }
00223 os << "\t";
00224 for (int i = 0; i < n; i++) {
00225 for (int j = 0; j < n; j++) {
00226 os.width(3);
00227 os << jump[f(i,j)] << " ";
00228 }
00229 os << std::endl << "\t";
00230 }
00231 os << std::endl;
00232 delete [] jump;
00233 }
00234 };
00235
00246 class KnightsReified : public Knights {
00247 public:
00248 KnightsReified(const SizeOptions& opt) : Knights(opt) {
00249 const int nn = n*n;
00250
00251
00252 IntVarArgs jump(nn);
00253 IntVarArgs pred(nn);
00254
00255 for (int i = nn; i--; ) {
00256 IntVar p(*this,0,nn-1); pred[i]=p;
00257 IntVar j(*this,0,nn-1); jump[i]=j;
00258 }
00259
00260
00261 rel(*this, jump[f(0,0)], IRT_EQ, 0);
00262 rel(*this, jump[f(1,2)], IRT_EQ, 1);
00263
00264 distinct(*this, jump, opt.icl());
00265 channel(*this, succ, pred, opt.icl());
00266
00267 for (int f = 0; f < nn; f++) {
00268 IntSet ds = neighbors(f);
00269 for (IntSetValues i(ds); i(); ++i)
00270 rel(*this,
00271 expr(*this, (jump[i.val()]-jump[f] == 1)),
00272 BOT_XOR,
00273 expr(*this, (jump[i.val()]-jump[f] == 1-nn)),
00274 expr(*this, (succ[f] == i.val())));
00275 dom(*this, pred[f], ds);
00276 dom(*this, succ[f], ds);
00277 rel(*this, succ[f], IRT_NQ, pred[f]);
00278 }
00279 }
00281 KnightsReified(bool share, KnightsReified& s) : Knights(share,s) {}
00283 virtual Space*
00284 copy(bool share) {
00285 return new KnightsReified(share,*this);
00286 }
00287 };
00288
00299 class KnightsCircuit : public Knights {
00300 public:
00301 KnightsCircuit(const SizeOptions& opt) : Knights(opt) {
00302
00303 rel(*this, succ[0], IRT_EQ, f(1,2));
00304
00305 circuit(*this, succ, opt.icl());
00306
00307 for (int f = 0; f < n*n; f++)
00308 dom(*this, succ[f], neighbors(f));
00309 }
00311 KnightsCircuit(bool share, KnightsCircuit& s) : Knights(share,s) {}
00313 virtual Space*
00314 copy(bool share) {
00315 return new KnightsCircuit(share,*this);
00316 }
00317 };
00318
00319
00320
00321
00322
00323
00324
00325 #if defined(GECODE_HAS_QT) && defined(GECODE_HAS_GIST)
00326
00327 class KnightsInspector : public Gist::Inspector {
00328 protected:
00330 QGraphicsScene* scene;
00332 QMainWindow* mw;
00334 static const int unit = 30;
00335 public:
00337 KnightsInspector(void) : scene(NULL), mw(NULL) {}
00339 virtual void inspect(const Space& s) {
00340 const Knights& k = static_cast<const Knights&>(s);
00341
00342 if (!scene)
00343 initialize();
00344 QList <QGraphicsItem*> itemList = scene->items();
00345 foreach (QGraphicsItem* i, scene->items()) {
00346 scene->removeItem(i);
00347 delete i;
00348 }
00349
00350 for (int i=0; i<k.n; i++) {
00351 for (int j=0; j<k.n; j++) {
00352 scene->addRect(i*unit,j*unit,unit,unit);
00353
00354 QPen pen(Qt::black, 2);
00355 if (!k.succ[i*k.n+j].assigned()) {
00356 pen.setColor(Qt::red);
00357 pen.setStyle(Qt::DotLine);
00358 pen.setWidth(0);
00359 }
00360 for (IntVarValues xv(k.succ[i*k.n+j]); xv(); ++xv) {
00361 int ky = xv.val() % k.n;
00362 int kx = xv.val() / k.n;
00363 scene->addLine(i*unit+unit/2,j*unit+unit/2,
00364 kx*unit+unit/2,ky*unit+unit/2,
00365 pen);
00366 }
00367
00368 }
00369 }
00370 mw->show();
00371 }
00372
00374 void initialize(void) {
00375 mw = new QMainWindow();
00376 scene = new QGraphicsScene();
00377 QGraphicsView* view = new QGraphicsView(scene);
00378 view->setRenderHints(QPainter::Antialiasing);
00379 mw->setCentralWidget(view);
00380 mw->setAttribute(Qt::WA_QuitOnClose, false);
00381 mw->setAttribute(Qt::WA_DeleteOnClose, false);
00382 QAction* closeWindow = new QAction("Close window", mw);
00383 closeWindow->setShortcut(QKeySequence("Ctrl+W"));
00384 mw->connect(closeWindow, SIGNAL(triggered()),
00385 mw, SLOT(close()));
00386 mw->addAction(closeWindow);
00387 }
00388
00390 virtual std::string name(void) { return "Board"; }
00392 virtual void finalize(void) {
00393 delete mw;
00394 mw = NULL;
00395 }
00396 };
00397 #endif
00398
00402 int
00403 main(int argc, char* argv[]) {
00404 SizeOptions opt("Knights");
00405 opt.iterations(100);
00406 opt.size(8);
00407 opt.propagation(Knights::PROP_CIRCUIT);
00408 opt.propagation(Knights::PROP_REIFIED, "reified");
00409 opt.propagation(Knights::PROP_CIRCUIT, "circuit");
00410 opt.branching(Knights::BRANCH_NAIVE);
00411 opt.branching(Knights::BRANCH_NAIVE, "reified");
00412 opt.branching(Knights::BRANCH_WARNSDORFF, "warnsdorff");
00413
00414 #if defined(GECODE_HAS_QT) && defined(GECODE_HAS_GIST)
00415 KnightsInspector ki;
00416 opt.inspect.click(&ki);
00417 #endif
00418
00419 opt.parse(argc,argv);
00420
00421 if (opt.propagation() == Knights::PROP_REIFIED) {
00422 Script::run<KnightsReified,DFS,SizeOptions>(opt);
00423 } else {
00424 Script::run<KnightsCircuit,DFS,SizeOptions>(opt);
00425 }
00426 return 0;
00427 }
00428
00429
00430