Generated on Wed Nov 1 15:04:27 2006 for Gecode by doxygen 1.4.5

knights.cc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Christian Schulte <schulte@gecode.org>
00004  *
00005  *  Copyright:
00006  *     Christian Schulte, 2001
00007  *
00008  *  Last modified:
00009  *     $Date: 2006-08-04 16:06:52 +0200 (Fri, 04 Aug 2006) $ by $Author: schulte $
00010  *     $Revision: 3517 $
00011  *
00012  *  This file is part of Gecode, the generic constraint
00013  *  development environment:
00014  *     http://www.gecode.org
00015  *
00016  *  See the file "LICENSE" for information on usage and
00017  *  redistribution of this file, and for a
00018  *     DISCLAIMER OF ALL WARRANTIES.
00019  *
00020  */
00021 
00022 #include "examples/support.hh"
00023 #include "gecode/minimodel.hh"
00024 
00035 class Knights : public Example {
00036 private:
00038   const int n;
00040   IntVarArray jump;
00041 public:
00042 
00044   int
00045   field(int i, int j) {
00046     return i*n+j;
00047   }
00048 
00050   Knights(const Options& opt)
00051     : n(opt.size), jump(this,n*n,0,n*n-1) {
00052     const int nn = n*n;
00053 
00054     // Map knight to its predecessor of succesor on board
00055     IntVarArgs pred(nn);
00056     IntVarArgs succ(nn);
00057     for (int i = nn; i--; ) {
00058       IntVar p(this,0,nn-1);
00059       IntVar s(this,0,nn-1);
00060       pred[i]=p; succ[i]=s;
00061     }
00062 
00063     // Place the first two knights
00064     rel(this, jump[field(0,0)], IRT_EQ, 0);
00065     rel(this, jump[field(1,2)], IRT_EQ, 1);
00066 
00067     distinct(this, jump, opt.icl);
00068 
00069     for (int f = 0; f < nn; f++) {
00070       int i = f / n;
00071       int j = f % n;
00072       // Compute array of neighbours
00073       int nbs[8];
00074       int n_nbs = 0;
00075 
00076       static const int moves[8][2] = {
00077         {-2,-1}, {-2,1}, {-1,-2}, {-1,2}, {1,-2}, {1,2}, {2,-1}, {2,1}
00078       };
00079 
00080       for (int nij = 0; nij<8 ; nij++) {
00081         int id = i + moves[nij][0];
00082         int jd = j + moves[nij][1];
00083         
00084         if ((id >= 0) && (jd >= 0) && (id < n) && (jd < n)) {
00085           int g = field(id,jd);
00086           nbs[n_nbs++] = g;
00087         
00088           BoolVar b(this,0,1);
00089 
00090           rel(this, succ[f], IRT_EQ, g, b);
00091           rel(this, pred[g], IRT_EQ, f, b);
00092 
00093           bool_xor(this,
00094                    post(this, ~(jump[g]-jump[f] == 1)),
00095                    post(this, ~(jump[g]-jump[f] == 1-nn)),
00096                    b);
00097         }
00098       }
00099         
00100       IntSet ds(nbs, n_nbs);
00101       dom(this, pred[f], ds);
00102       dom(this, succ[f], ds);
00103       rel(this, succ[f], IRT_NQ, pred[f]);
00104     }
00105     branch(this, succ, BVAR_NONE, BVAL_MIN);
00106   }
00107 
00109   Knights(bool share, Knights& s) : Example(share,s), n(s.n) {
00110     jump.update(this, share, s.jump);
00111   }
00113   virtual Space*
00114   copy(bool share) {
00115     return new Knights(share,*this);
00116   }
00118   virtual void
00119   print(void) {
00120     std::cout << "\t";
00121     for (int i = 0; i < n; i++) {
00122       for (int j = 0; j < n; j++) {
00123         std::cout.width(3);
00124         std::cout << jump[field(i,j)] << " ";
00125       }
00126       std::cout << std::endl << "\t";
00127     }
00128     std::cout << std::endl;
00129   }
00130 };
00131 
00135 int
00136 main(int argc, char** argv) {
00137   Options opt("Knights");
00138   opt.iterations = 100;
00139   opt.size       = 8;
00140   opt.parse(argc,argv);
00141   Example::run<Knights,DFS>(opt);
00142   return 0;
00143 }
00144 
00145 // STATISTICS: example-any
00146