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