Generated on Mon Aug 25 11:35:32 2008 for Gecode by doxygen 1.5.6

knights.cc

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Christian Schulte <schulte@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2001
00008  *
00009  *  Last modified:
00010  *     $Date: 2007-11-30 13:58:34 +0100 (Fri, 30 Nov 2007) $ by $Author: tack $
00011  *     $Revision: 5524 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  *  Permission is hereby granted, free of charge, to any person obtaining
00018  *  a copy of this software and associated documentation files (the
00019  *  "Software"), to deal in the Software without restriction, including
00020  *  without limitation the rights to use, copy, modify, merge, publish,
00021  *  distribute, sublicense, and/or sell copies of the Software, and to
00022  *  permit persons to whom the Software is furnished to do so, subject to
00023  *  the following conditions:
00024  *
00025  *  The above copyright notice and this permission notice shall be
00026  *  included in all copies or substantial portions of the Software.
00027  *
00028  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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     // Map knight to its predecessor of succesor on board
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     // Place the first two knights
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       // Array of neighbours
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     // Fix the first move
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       // Array of neighbours
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 // STATISTICS: example-any
00220