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 <gecode/driver.hh>
00039 #include <gecode/int.hh>
00040 #include <gecode/minimodel.hh>
00041
00042 using namespace Gecode;
00043
00044 namespace {
00049 class OpenShopSpec {
00050 public:
00051 const int m;
00052 const int n;
00053 const int* p;
00055 OpenShopSpec(int m0, int n0, const int* p0) : m(m0), n(n0), p(p0) {}
00056 };
00057
00058 extern OpenShopSpec examples[];
00059 extern const unsigned int n_examples;
00060 }
00061
00068 class OpenShop : public MinimizeScript {
00069 protected:
00071 const OpenShopSpec& spec;
00073 BoolVarArray b;
00075 IntVar makespan;
00077 IntVarArray _start;
00078
00080 class Task {
00081 public:
00082 int j;
00083 int m;
00084 int p;
00086 Task(void) {}
00088 Task(int j0, int m0, int p0) : j(j0), m(m0), p(p0) {}
00089 };
00090
00100 void crosh(Matrix<IntArgs>& dur, int& minmakespan, int& maxmakespan) {
00101 Support::RandomGenerator rnd;
00102
00103
00104 maxmakespan = 0;
00105 for (int i=0; i<spec.m; i++)
00106 for (int j=0; j<spec.n; j++)
00107 maxmakespan += dur(i,j);
00108
00109
00110 minmakespan = 0;
00111 for (int i=0; i<spec.m; i++) {
00112 int ms = 0;
00113 for (int j=0; j<spec.n; j++) {
00114 ms += dur(i,j);
00115 }
00116 minmakespan = std::max(minmakespan, ms);
00117 }
00118 for (int j=0; j<spec.n; j++) {
00119 int ms = 0;
00120 for (int i=0; i<spec.m; i++) {
00121 ms += dur(i,j);
00122 }
00123 minmakespan = std::max(minmakespan, ms);
00124 }
00125
00126 Region re(*this);
00127 int* ct_j = re.alloc<int>(spec.n);
00128 int* ct_m = re.alloc<int>(spec.m);
00129 Task* tasks = re.alloc<Task>(spec.n*spec.m);
00130 int k=0;
00131 for (int i=spec.m; i--;)
00132 for (int j=spec.n; j--;)
00133 new (&tasks[k++]) Task(j,i,dur(i,j));
00134 int* t0_tasks = re.alloc<int>(spec.n*spec.m);
00135
00136 bool stopCROSH = false;
00137
00138 int maxIterations;
00139 switch (spec.n) {
00140 case 3: maxIterations = 5; break;
00141 case 4: maxIterations = 25; break;
00142 case 5: maxIterations = 50; break;
00143 case 6: maxIterations = 1000; break;
00144 case 7: maxIterations = 10000; break;
00145 case 8: maxIterations = 10000; break;
00146 case 9: maxIterations = 10000; break;
00147 default: maxIterations = 25000; break;
00148 }
00149 int iteration = 0;
00150 while (!stopCROSH && maxmakespan > minmakespan) {
00151 for (int i=spec.n; i--;) ct_j[i] = 0;
00152 for (int i=spec.m; i--;) ct_m[i] = 0;
00153 int cmax = 0;
00154 int u = spec.n*spec.m;
00155 while (u > 0) {
00156 int u_t0 = 0;
00157 int t0 = maxmakespan;
00158 for (int i=0; i<u; i++) {
00159 const Task& t = tasks[i];
00160 int est = std::max(ct_j[t.j], ct_m[t.m]);
00161 if (est < t0) {
00162 t0 = est;
00163 t0_tasks[0] = i;
00164 u_t0 = 1;
00165 } else if (est == t0) {
00166 t0_tasks[u_t0++] = i;
00167 }
00168 }
00169 int t_j0m0;
00170 if (iteration == 0) {
00171
00172 t_j0m0 = 0;
00173 for (int i=1; i<u_t0; i++)
00174 if (tasks[t0_tasks[i]].p > tasks[t0_tasks[t_j0m0]].p)
00175 t_j0m0 = i;
00176 } else {
00177 t_j0m0 = rnd(u_t0);
00178 }
00179 const Task& t = tasks[t0_tasks[t_j0m0]];
00180 int ect = t0 + t.p;
00181 ct_j[t.j] = ect;
00182 ct_m[t.m] = ect;
00183 std::swap(tasks[--u],tasks[t0_tasks[t_j0m0]]);
00184 cmax = std::max(cmax, ect);
00185 if (cmax > maxmakespan)
00186 break;
00187 }
00188
00189 maxmakespan = std::min(maxmakespan,cmax);
00190 if (iteration++ > maxIterations)
00191 stopCROSH = true;
00192 }
00193 }
00194 public:
00196 enum {
00197 SEARCH_BAB,
00198 SEARCH_RESTART
00199 };
00201 OpenShop(const SizeOptions& opt)
00202 : spec(examples[opt.size()]),
00203 b(*this, (spec.n+spec.m-2)*spec.n*spec.m/2, 0,1),
00204 makespan(*this, 0, Int::Limits::max),
00205 _start(*this, spec.m*spec.n, 0, Int::Limits::max) {
00206
00207 Matrix<IntVarArray> start(_start, spec.m, spec.n);
00208 IntArgs _dur(spec.m*spec.n, spec.p);
00209 Matrix<IntArgs> dur(_dur, spec.m, spec.n);
00210
00211 int minmakespan;
00212 int maxmakespan;
00213 crosh(dur, minmakespan, maxmakespan);
00214 rel(*this, makespan <= maxmakespan);
00215 rel(*this, makespan >= minmakespan);
00216
00217 int k=0;
00218 for (int m=0; m<spec.m; m++)
00219 for (int j0=0; j0<spec.n-1; j0++)
00220 for (int j1=j0+1; j1<spec.n; j1++) {
00221
00222 rel(*this,
00223 b[k] == (start(m,j0) + dur(m,j0) <= start(m,j1)));
00224 rel(*this,
00225 b[k++] == (start(m,j1) + dur(m,j1) > start(m,j0)));
00226 }
00227
00228 for (int j=0; j<spec.n; j++)
00229 for (int m0=0; m0<spec.m-1; m0++)
00230 for (int m1=m0+1; m1<spec.m; m1++) {
00231
00232 rel(*this,
00233 b[k] == (start(m0,j) + dur(m0,j) <= start(m1,j)));
00234 rel(*this,
00235 b[k++] == (start(m1,j) + dur(m1,j) > start(m0,j)));
00236 }
00237
00238
00239 for (int m=0; m<spec.m; m++) {
00240 for (int j=0; j<spec.n; j++) {
00241 rel(*this, start(m,j) + dur(m,j) <= makespan);
00242 }
00243 }
00244
00245
00246 branch(*this, b, INT_VAR_AFC_MAX, INT_VAL_MAX);
00247
00248 assign(*this, _start, INT_ASSIGN_MIN);
00249
00250 assign(*this, makespan, INT_ASSIGN_MIN);
00251 }
00252
00254 OpenShop(bool share, OpenShop& s) : MinimizeScript(share,s), spec(s.spec) {
00255 b.update(*this, share, s.b);
00256 makespan.update(*this, share, s.makespan);
00257 _start.update(*this, share, s._start);
00258 }
00259
00261 virtual Space*
00262 copy(bool share) {
00263 return new OpenShop(share,*this);
00264 }
00265
00267 virtual IntVar
00268 cost(void) const {
00269 return makespan;
00270 }
00271
00273 class PrintTask {
00274 public:
00275 int start;
00276 int job;
00277 int p;
00279 bool operator()(const PrintTask& t1, const PrintTask& t2) {
00280 return t1.start < t2.start;
00281 }
00282 };
00283
00285 virtual void
00286 print(std::ostream& os) const {
00287 Region re(*this);
00288 PrintTask* m = re.alloc<PrintTask>(spec.n);
00289 for (int i=0; i<spec.m; i++) {
00290 int k=0;
00291 for (int j=0; j<spec.n; j++) {
00292 m[k].start = _start[i*spec.n+j].val();
00293 m[k].job = j;
00294 m[k].p = spec.p[i*spec.n+j];
00295 k++;
00296 }
00297 Support::quicksort(m, spec.n, m[0]);
00298 os << "Machine " << i << ": ";
00299 for (int j=0; j<spec.n; j++)
00300 os << "\t" << m[j].job << "("<<m[j].p<<")";
00301 os << " = " << m[spec.n-1].start+m[spec.n-1].p << std::endl;
00302 }
00303 os << "Makespan: " << makespan << std::endl;
00304 }
00305
00306 };
00307
00311 int
00312 main(int argc, char* argv[]) {
00313 SizeOptions opt("OpenShop");
00314 opt.iterations(500);
00315 opt.size(0);
00316 opt.solutions(0);
00317 opt.search(OpenShop::SEARCH_BAB);
00318 opt.search(OpenShop::SEARCH_BAB, "bab");
00319 opt.search(OpenShop::SEARCH_RESTART, "restart");
00320 opt.parse(argc,argv);
00321 if (opt.size() >= n_examples) {
00322 std::cerr << "Error: size must be between 0 and "
00323 << n_examples-1 << std::endl;
00324 return 1;
00325 }
00326 switch (opt.search()) {
00327 case OpenShop::SEARCH_BAB:
00328 MinimizeScript::run<OpenShop,BAB,SizeOptions>(opt); break;
00329 case OpenShop::SEARCH_RESTART:
00330 MinimizeScript::run<OpenShop,Restart,SizeOptions>(opt); break;
00331 }
00332 return 0;
00333 }
00334
00335 namespace {
00336
00345
00346 const int ex0_p[] = {
00347 661,6,333,
00348 168,489,343,
00349 171,505,324
00350 };
00351 OpenShopSpec ex0(3,3,ex0_p);
00352
00353 const int ex1_p[] = {
00354 54, 34, 61, 2,
00355 9, 15, 89, 70,
00356 38, 19, 28, 87,
00357 95, 34, 7, 29
00358 };
00359 OpenShopSpec ex1(4,4,ex1_p);
00360
00361 const int ex2_p[] = {
00362 5, 70, 45, 83,
00363 24, 80, 58, 45,
00364 29, 56, 29, 61,
00365 43, 64, 45, 74
00366 };
00367 OpenShopSpec ex2(4,4,ex2_p);
00368
00369 const int ex3_p[] = {
00370 89, 39, 54, 34, 71, 92, 56,
00371 19, 13, 81, 46, 91, 73, 27,
00372 66, 95, 48, 24, 96, 18, 14,
00373 48, 46, 78, 94, 19, 68, 63,
00374 60, 28, 91, 75, 52, 9, 7,
00375 33, 98, 37, 11, 2, 30, 38,
00376 83, 45, 37, 77, 52, 88, 52
00377 };
00378 OpenShopSpec ex3(7,7,ex3_p);
00379
00380 const int ex4_p[] = {
00381 49, 58, 37, 79, 16, 64, 71, 65, 6, 44, 17, 85, 99, 57, 89, 4, 16, 8, 40, 66,
00382 43, 65, 42, 35, 57, 3, 8, 65, 79, 76, 82, 80, 96, 82, 98, 57, 73, 43, 6, 20,
00383 82, 49, 7, 18, 94, 76, 41, 17, 43, 15, 53, 10, 83, 24, 79, 62, 53, 77, 23, 70,
00384 18, 30, 80, 7, 97, 84, 10, 27, 7, 91, 14, 12, 7, 31, 24, 97, 16, 33, 99, 15,
00385 31, 65, 51, 95, 45, 70, 57, 10, 84, 52, 28, 43, 54, 40, 83, 9, 21, 57, 45, 67,
00386 70, 45, 48, 39, 10, 37, 22, 53, 48, 50, 76, 48, 57, 6, 43, 13, 45, 93, 42, 11,
00387 80, 5, 53, 97, 75, 22, 10, 70, 79, 92, 96, 18, 57, 3, 82, 52, 1, 21, 23, 38,
00388 43, 79, 67, 57, 33, 52, 1, 44, 82, 10, 27, 23, 89, 9, 62, 6, 38, 33, 37, 22,
00389 68, 20, 5, 25, 16, 80, 13, 73, 35, 36, 13, 53, 97, 50, 17, 54, 35, 86, 24, 56,
00390 60, 83, 8, 81, 3, 4, 48, 14, 77, 10, 71, 57, 86, 94, 49, 36, 62, 62, 41, 56,
00391 31, 77, 5, 97, 19, 19, 31, 19, 26, 41, 77, 64, 74, 11, 98, 30, 22, 22, 33, 61,
00392 7, 89, 46, 13, 33, 55, 84, 16, 21, 45, 15, 71, 57, 42, 82, 13, 62, 98, 36, 45,
00393 84, 90, 20, 61, 24, 59, 8, 49, 53, 53, 83, 76, 28, 62, 59, 11, 41, 2, 58, 46,
00394 32, 23, 53, 5, 8, 91, 97, 53, 90, 90, 28, 16, 61, 27, 32, 74, 23, 11, 57, 20,
00395 62, 85, 79, 96, 62, 85, 43, 53, 12, 36, 95, 37, 2, 48, 46, 81, 97, 54, 5, 77,
00396 57, 35, 41, 55, 72, 98, 22, 81, 6, 8, 70, 64, 55, 53, 7, 38, 58, 30, 83, 81,
00397 15, 11, 24, 63, 27, 90, 35, 22, 53, 22, 66, 75, 59, 80, 31, 91, 63, 82, 99, 62,
00398 4, 18, 99, 6, 65, 21, 28, 93, 16, 26, 1, 16, 46, 59, 45, 90, 69, 76, 25, 53,
00399 50, 24, 66, 2, 17, 85, 5, 86, 4, 88, 44, 5, 29, 19, 27, 14, 36, 57, 59, 15,
00400 71, 79, 7, 61, 45, 72, 61, 45, 61, 54, 90, 33, 81, 5, 45, 64, 87, 82, 61, 8
00401 };
00402 OpenShopSpec ex4(20,20,ex4_p);
00403
00405 OpenShopSpec examples[] = { ex0, ex1, ex2, ex3, ex4 };
00407 const unsigned int n_examples = sizeof(examples) / sizeof(OpenShopSpec);
00408
00410 }
00411
00412