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

domino.cc

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Guido Tack <tack@gecode.org>
00005  *     Mikael Lagerkvist <lagerkvist@gecode.org>
00006  *
00007  *  Copyright:
00008  *     Guido Tack, 2006
00009  *     Mikael Lagerkvist, 2006
00010  *
00011  *  Last modified:
00012  *     $Date: 2008-08-21 15:20:13 +0200 (Thu, 21 Aug 2008) $ by $Author: schulte $
00013  *     $Revision: 7674 $
00014  *
00015  *  This file is part of Gecode, the generic constraint
00016  *  development environment:
00017  *     http://www.gecode.org
00018  *
00019  *  Permission is hereby granted, free of charge, to any person obtaining
00020  *  a copy of this software and associated documentation files (the
00021  *  "Software"), to deal in the Software without restriction, including
00022  *  without limitation the rights to use, copy, modify, merge, publish,
00023  *  distribute, sublicense, and/or sell copies of the Software, and to
00024  *  permit persons to whom the Software is furnished to do so, subject to
00025  *  the following conditions:
00026  *
00027  *  The above copyright notice and this permission notice shall be
00028  *  included in all copies or substantial portions of the Software.
00029  *
00030  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00031  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00032  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00033  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00034  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00035  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00036  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00037  *
00038  */
00039 
00040 #include "examples/support.hh"
00041 #include "gecode/minimodel.hh"
00042 
00043 namespace {
00044 
00049   extern const int *specs[];
00054   extern const unsigned int n_examples;
00055 
00056 }
00057 
00069 class Domino : public Example {
00070 private:
00072   const int *spec;
00074   int width;
00076   int height;
00077   
00079   IntVarArray x;
00080 
00081 public:
00083   Domino(const SizeOptions& opt)
00084     : spec(specs[opt.size()]), 
00085       width(spec[0]), height(spec[1]),
00086       x(this, (width+1)*height, 0, 28) {
00087     spec+=2; // skip board size information
00088     
00089     // Copy spec information to the board
00090     IntArgs board((width+1)*height);
00091     for (int i=0; i<width; i++)
00092       for (int j=0; j<height; j++)
00093         board[j*(width+1)+i] = spec[j*width+i];    
00094     
00095     // Initialize the separator column in the board
00096     for (int i=0; i<height; i++) {
00097       board[i*(width+1)+8] = -1;
00098       post(this, x[i*(width+1)+8]==28);
00099     }
00100 
00101     // Variables representing the coordinates of the first
00102     // and second half of a domino piece
00103     IntVarArray p1(this, 28, 0, (width+1)*height-1);
00104     IntVarArray p2(this, 28, 0, (width+1)*height-1);
00105     
00106 
00107     int dominoCount = 0;
00108       
00109     int possibleDiffsA[] = {1, width+1};
00110     IntSet possibleDiffs(possibleDiffsA, 2);
00111     
00112     for (int i=0; i<=6; i++)
00113       for (int j=i; j<=6; j++) {
00114         
00115         // The two coordinates must be adjacent.
00116         // I.e., they may differ by 1 or by the width.
00117         // The separator column makes sure that a field
00118         // at the right border is not adjacent to the first field
00119         // in the next row.
00120         IntVar diff(this, possibleDiffs);
00121         abs(this, minus(this, p1[dominoCount], p2[dominoCount]),
00122             diff, ICL_DOM);
00123         
00124         // If the piece is symmetrical, order the locations
00125         if (i == j)
00126           rel(this, p1[dominoCount], IRT_LE, p2[dominoCount]);
00127         
00128         // Link the current piece to the board
00129         element(this, board, p1[dominoCount], i);
00130         element(this, board, p2[dominoCount], j);
00131         
00132         // Link the current piece to the array where its
00133         // number is stored.
00134         element(this, x, p1[dominoCount], dominoCount);
00135         element(this, x, p2[dominoCount], dominoCount);
00136         dominoCount++;
00137       }
00138 
00139     // Branch by piece
00140     IntVarArgs ps(28*2);
00141     for (int i=0; i<28; i++) {
00142       ps[2*i]   = p1[i];
00143       ps[2*i+1] = p2[i];
00144     }
00145 
00146     // Install branchings
00147     branch(this, ps, INT_VAR_NONE, INT_VAL_MIN);
00148   }
00149 
00151   virtual void
00152   print(std::ostream& os) {
00153     for (int h = 0; h < height; ++h) {
00154       os << "\t";
00155       for (int w = 0; w < width; ++w) {
00156         int val =  x[h*(width+1)+w].min();
00157         char c = val < 10 ? '0'+val : 'A' + (val-10);
00158         os << c;
00159       }
00160       os << std::endl;
00161     }
00162     os << std::endl;
00163   }
00165   Domino(bool share, Domino& s) :
00166     Example(share,s), spec(s.spec), width(s.width), height(s.height) {
00167       x.update(this, share, s.x);
00168   }
00170   virtual Space*
00171   copy(bool share) {
00172     return new Domino(share,*this);
00173   }
00174 
00175 };
00176 
00177 
00181 int
00182 main(int argc, char* argv[]) {
00183   SizeOptions opt("Domino");
00184   opt.size(0);
00185   opt.parse(argc,argv);
00186   if (opt.size() >= n_examples) {
00187     std::cerr << "Error: size must be between 0 and "
00188               << n_examples-1 << std::endl;
00189     return 1;
00190   }
00191   Example::run<Domino,DFS,SizeOptions>(opt);
00192   return 0;
00193 }
00194 
00195 
00196 namespace {
00197 
00203   
00205   const int domino0[] =
00206     { // width*height of the board
00207       8,7,
00208       // the board itself
00209       2,1,0,3,0,4,5,5,
00210       6,2,0,6,3,1,4,0,
00211       3,2,3,6,2,5,4,3,
00212       5,4,5,1,1,2,1,2,
00213       0,0,1,5,0,5,4,4,
00214       4,6,2,1,3,6,6,1,
00215       4,2,0,6,5,3,3,6
00216     };
00217   
00219   const int domino1[] =
00220     { // width*height of the board
00221       8,7,
00222       // the board itself
00223       5,1,2,4,6,2,0,5,
00224       6,6,4,3,5,0,1,5,
00225       2,0,4,0,4,0,5,0,
00226       6,1,3,6,3,5,4,3,
00227       3,1,0,1,2,2,1,4,
00228       3,6,6,2,4,0,5,4,
00229       1,3,6,1,2,3,5,2
00230     };
00231   
00233   const int domino2[] =
00234     { // width*height of the board
00235       8,7,
00236       // the board itself
00237       4,4,5,4,0,3,6,5,
00238       1,6,0,1,5,3,4,1,
00239       2,6,2,2,5,3,6,0,
00240       1,3,0,6,4,4,2,3,
00241       3,5,5,2,4,2,2,1,
00242       2,1,3,3,5,6,6,1,
00243       5,1,6,0,0,0,4,0
00244     };
00245   
00247   const int domino3[] =
00248     { // width*height of the board
00249       8,7,
00250       // the board itself
00251       3,0,2,3,3,4,4,3,
00252       6,5,3,4,2,0,2,1,
00253       6,5,1,2,3,0,2,0,
00254       4,5,4,1,6,6,2,5,
00255       4,3,6,1,0,4,5,5,
00256       1,3,2,5,6,0,0,1,
00257       0,5,4,6,2,1,6,1
00258     };
00259   
00261   const int domino4[] =
00262     { // width*height of the board
00263       8,7,
00264       // the board itself
00265       4,1,5,2,4,4,6,2,
00266       2,5,6,1,4,6,0,2,
00267       6,5,1,1,0,1,4,3,
00268       6,2,1,1,3,2,0,6,
00269       3,6,3,3,5,5,0,5,
00270       3,0,1,0,0,5,4,3,
00271       3,2,4,5,4,2,6,0
00272     };
00273   
00275   const int domino5[] =
00276     { // width*height of the board
00277       8,7,
00278       // the board itself
00279       4,1,2,1,0,2,4,4,
00280       5,5,6,6,0,4,6,3,
00281       6,0,5,1,1,0,5,3,
00282       3,4,2,2,0,3,1,2,
00283       3,6,5,6,1,2,3,2,
00284       2,5,0,6,6,3,3,5,
00285       4,1,0,0,4,1,4,5
00286     };
00287   
00289   const int *specs[] =
00290     {domino0,domino1,domino2,domino3,domino4,domino5};
00292   const unsigned n_examples = sizeof(specs)/sizeof(int*);
00294 
00295 }
00296 
00297 // STATISTICS: example-any