00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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
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
00146