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

packing.cc

Go to the documentation of this file.
00001 /*
00002  *  Main authors:
00003  *     Christian Schulte <schulte@gecode.org>
00004  *     Mikael Lagerkvist <lagerkvist@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Christian Schulte, 2003
00008  *     Mikael Lagerkvist, 2005
00009  *
00010  *  Last modified:
00011  *     $Date: 2006-08-04 16:06:52 +0200 (Fri, 04 Aug 2006) $ by $Author: schulte $
00012  *     $Revision: 3517 $
00013  *
00014  *  This file is part of Gecode, the generic constraint
00015  *  development environment:
00016  *     http://www.gecode.org
00017  *
00018  *  See the file "LICENSE" for information on usage and
00019  *  redistribution of this file, and for a
00020  *     DISCLAIMER OF ALL WARRANTIES.
00021  *
00022  */
00023 
00024 #include "examples/support.hh"
00025 #include "gecode/minimodel.hh"
00026 
00032 //@
00034 class PackingSpec {
00035 public:
00036   int x; int y;
00037   int n; const int* s;
00038   PackingSpec(int x0, int y0, const int s0[]) :
00039     x(x0), y(y0), s(s0) {
00040     int i = 0;
00041     while (s[i]) i++;
00042     n = i;
00043   }
00044 };
00045 
00046 static const int s0_s[] = {2,2,2,2,0};
00047 static const PackingSpec s0(4,4,s0_s);
00048 
00049 static const int s1_s[] = {3,2,2,1,1,1,0};
00050 static const PackingSpec s1(5,4,s1_s);
00051 
00052 static const int s2_s[] = {6,4,4,4,2,2,2,2,0};
00053 static PackingSpec s2(10,10,s2_s);
00054 
00055 static const int s3_s[] = {9,8,8,7,5,4,4,4,4,4,3,3,3,2,2,1,1,0};
00056 static const PackingSpec s3(20,20,s3_s);
00057 
00058 static const int s4_s[] = {18,15,14,10,9,8,7,4,1,0};
00059 static const PackingSpec s4(32,33,s4_s);
00060 
00061 static const int s5_s[] = {25,24,23,22,19,17,11,6,5,3,0};
00062 static const PackingSpec s5(65,47,s5_s);
00063 
00064 static const int s6_s[] = {50,42,37,35,33,29,27,25,24,19,18,
00065                            17,16,15,11,9,8,7,6,4,2,0};
00066 static const PackingSpec s6(112,112,s6_s);
00067 
00068 static const int s7_s[] = {81,64,56,55,51,43,39,38,35,33,31,30,29,20,
00069                            18,16,14,9,8,5,4,3,2,1,0};
00070 static const PackingSpec s7(175,175,s7_s);
00071 
00072 static const PackingSpec* specs[] = {&s0,&s1,&s2,&s3,&s4,&s5,&s6,&s7};
00073 static const unsigned int n_examples = sizeof(specs) / sizeof(PackingSpec*);
00075 
00081 class Packing : public Example {
00082 protected:
00084   const PackingSpec& s;
00086   IntVarArray x;
00088   IntVarArray y;
00089 public:
00091   Packing(const Options& opt)
00092     : s(*specs[opt.size]),
00093       x(this,s.n,0,s.x-1), y(this,s.n,0,s.y-1) {
00094 
00095     // Restrict position according to square size
00096     for (int i=s.n; i--; ) {
00097       rel(this, x[i], IRT_LQ, s.x-s.s[i]);
00098       rel(this, y[i], IRT_LQ, s.y-s.s[i]);
00099     }
00100 
00101     // Squares do not overlap
00102     for (int i=0; i<s.n; i++)
00103       for (int j=i+1; j<s.n; j++)
00104         post(this, tt(~(x[j]-x[i] >= s.s[i]) || ~(x[i]-x[j] >= s.s[j]) ||
00105                       ~(y[j]-y[i] >= s.s[i]) || ~(y[i]-y[j] >= s.s[j])));
00106 
00107     /*
00108      * Symmetry breaking
00109      *
00110      */
00111     for (int i=s.n-1; i--; )
00112       if (s.s[i] == s.s[i+1])
00113         rel(this, x[i], IRT_LQ, x[i+1]);
00114 
00115     /*
00116      * Capacity constraints
00117      *
00118      */
00119     if (opt.naive) {
00120       IntArgs sa(s.n,s.s);
00121       BoolVarArgs b(s.n);
00122       for (int cx=0; cx<s.x; cx++) {
00123         for (int i=0; i<s.n; i++) {
00124           BoolVar b_cx(this,0,1);
00125           dom(this, x[i], cx-s.s[i]+1, cx, b_cx);
00126           b[i] = b_cx;
00127         }
00128         linear(this, sa, b, IRT_EQ, s.y);
00129       }
00130       for (int cy=0; cy<s.y; cy++) {
00131         for (int i=0; i<s.n; i++) {
00132           BoolVar b_cy(this,0,1);
00133           dom(this, y[i], cy-s.s[i]+1, cy, b_cy);
00134           b[i] = b_cy;
00135         }
00136         linear(this, sa, b, IRT_EQ, s.x);
00137       }
00138     } else {
00139       IntArgs m(s.n), dh(s.n);
00140       for (int i = s.n; i--; ) {
00141         m[i]  = 0;
00142         dh[i] = s.s[i];
00143       }
00144       IntVarArgs e(s.n);
00145       IntArgs limit(1);
00146       {
00147         // x-direction
00148         for (int i = s.n; i--; ) {
00149           IntVar ei(this, 0, s.x);
00150           e[i] = ei;
00151         }
00152         limit[0] = s.y;
00153         cumulatives(this, m, x, dh, e, dh, limit,  true);
00154         cumulatives(this, m, x, dh, e, dh, limit, false);
00155       }
00156       {
00157         // y-direction
00158         for (int i = s.n; i--; ) {
00159           IntVar ei(this, 0, s.y);
00160           e[i] = ei;
00161         }
00162         limit[0] = s.x;
00163         cumulatives(this, m, y, dh, e, dh, limit,  true);
00164         cumulatives(this, m, y, dh, e, dh, limit, false);
00165       }
00166     }
00167 
00168     branch(this, x, BVAR_MIN_MIN, BVAL_MIN);
00169     branch(this, y, BVAR_MIN_MIN, BVAL_MIN);
00170   }
00171 
00173   Packing(bool share, Packing& s) : Example(share,s), s(s.s) {
00174     x.update(this, share, s.x);
00175     y.update(this, share, s.y);
00176   }
00178   virtual Space*
00179   copy(bool share) {
00180     return new Packing(share,*this);
00181   }
00183   virtual void
00184   print(void) {
00185     std::cout << "\t";
00186     for (int i=0; i<s.n; i++)
00187       std::cout << "(" << x[i] << "," << y[i] << ") ";
00188     std::cout << std::endl;
00189   }
00190 };
00191 
00195 int
00196 main(int argc, char** argv) {
00197   Options opt("Packing");
00198   opt.naive = true;
00199   opt.size  = 7;
00200   opt.parse(argc,argv);
00201   if (opt.size >= n_examples) {
00202     std::cerr << "Error: size must be between 0 and " << n_examples - 1
00203               << std::endl;
00204     return 1;
00205   }
00206   Example::run<Packing,DFS>(opt);
00207   return 0;
00208 }
00209 
00210 // STATISTICS: example-any
00211