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 #include "examples/support.hh"
00039 #include "gecode/minimodel.hh"
00040
00042 class Knights : public Example {
00043 protected:
00045 const int n;
00047 IntVarArray succ;
00048 public:
00050 enum {
00051 PROP_REIFIED,
00052 PROP_CIRCUIT
00053 };
00055 int
00056 field(int x, int y) {
00057 return x*n+y;
00058 }
00060 void
00061 neighbours(int f, int nbs[8], int& n_nbs) {
00062 n_nbs=0;
00063 int x = f / n;
00064 int y = f % n;
00065 for (int i=0;i<8;i++) {
00066 static const int moves[8][2] = {
00067 {-2,-1}, {-2,1}, {-1,-2}, {-1,2}, {1,-2}, {1,2}, {2,-1}, {2,1}
00068 };
00069 int nx=x+moves[i][0];
00070 int ny=y+moves[i][1];
00071 if ((nx >= 0) && (nx < n) && (ny >= 0) && (ny < n))
00072 nbs[n_nbs++]=field(nx,ny);
00073 }
00074 }
00076 Knights(const SizeOptions& opt)
00077 : n(opt.size()), succ(this,n*n,0,n*n-1) {}
00079 Knights(bool share, Knights& s) : Example(share,s), n(s.n) {
00080 succ.update(this, share, s.succ);
00081 }
00083 virtual void
00084 print(std::ostream& os) {
00085 int* jump = new int[n*n];
00086 {
00087 int j=0;
00088 for (int i=0; i<n*n; i++) {
00089 jump[j]=i; j=succ[j].min();
00090 }
00091 }
00092 os << "\t";
00093 for (int i = 0; i < n; i++) {
00094 for (int j = 0; j < n; j++) {
00095 os.width(3);
00096 os << jump[field(i,j)] << " ";
00097 }
00098 os << std::endl << "\t";
00099 }
00100 os << std::endl;
00101 delete [] jump;
00102 }
00103 };
00104
00115 class KnightsReified : public Knights {
00116 public:
00117 KnightsReified(const SizeOptions& opt) : Knights(opt) {
00118 const int nn = n*n;
00119
00120
00121 IntVarArgs jump(nn);
00122 IntVarArgs pred(nn);
00123
00124 for (int i = nn; i--; ) {
00125 IntVar p(this,0,nn-1); pred[i]=p;
00126 IntVar j(this,0,nn-1); jump[i]=j;
00127 }
00128
00129
00130 rel(this, jump[field(0,0)], IRT_EQ, 0);
00131 rel(this, jump[field(1,2)], IRT_EQ, 1);
00132
00133 distinct(this, jump, opt.icl());
00134 channel(this, succ, pred, opt.icl());
00135
00136 for (int f = 0; f < nn; f++) {
00137
00138 int nbs[8]; int n_nbs = 0;
00139 neighbours(f, nbs, n_nbs);
00140 for (int i=n_nbs; i--; )
00141 rel(this,
00142 post(this, ~(jump[nbs[i]]-jump[f] == 1)),
00143 BOT_XOR,
00144 post(this, ~(jump[nbs[i]]-jump[f] == 1-nn)),
00145 post(this, ~(succ[f] == nbs[i])));
00146
00147 IntSet ds(nbs, n_nbs);
00148 dom(this, pred[f], ds);
00149 dom(this, succ[f], ds);
00150 rel(this, succ[f], IRT_NQ, pred[f]);
00151 }
00152 branch(this, succ, INT_VAR_NONE, INT_VAL_MIN);
00153 }
00155 KnightsReified(bool share, KnightsReified& s) : Knights(share,s) {}
00157 virtual Space*
00158 copy(bool share) {
00159 return new KnightsReified(share,*this);
00160 }
00161 };
00162
00173 class KnightsCircuit : public Knights {
00174 public:
00175 KnightsCircuit(const SizeOptions& opt) : Knights(opt) {
00176
00177 rel(this, succ[0], IRT_EQ, field(1,2));
00178
00179 circuit(this, succ, opt.icl());
00180
00181 for (int f = 0; f < n*n; f++) {
00182
00183 int nbs[8]; int n_nbs = 0;
00184 neighbours(f, nbs, n_nbs);
00185 IntSet ds(nbs, n_nbs);
00186 dom(this, succ[f], ds);
00187 }
00188 branch(this, succ, INT_VAR_NONE, INT_VAL_MIN);
00189 }
00191 KnightsCircuit(bool share, KnightsCircuit& s) : Knights(share,s) {}
00193 virtual Space*
00194 copy(bool share) {
00195 return new KnightsCircuit(share,*this);
00196 }
00197 };
00198
00202 int
00203 main(int argc, char* argv[]) {
00204 SizeOptions opt("Knights");
00205 opt.iterations(100);
00206 opt.size(8);
00207 opt.propagation(Knights::PROP_CIRCUIT);
00208 opt.propagation(Knights::PROP_REIFIED, "reified");
00209 opt.propagation(Knights::PROP_CIRCUIT, "circuit");
00210 opt.parse(argc,argv);
00211 if (opt.propagation() == Knights::PROP_REIFIED) {
00212 Example::run<KnightsReified,DFS,SizeOptions>(opt);
00213 } else {
00214 Example::run<KnightsCircuit,DFS,SizeOptions>(opt);
00215 }
00216 return 0;
00217 }
00218
00219
00220