Actual model
| 463 | }; |
| 464 | /// Actual model |
| 465 | JobShopSolve(const JobShopOptions& o) |
| 466 | : JobShopBase(o), |
| 467 | sorder(*this, spec.machines()*spec.jobs()*(spec.jobs()-1)/2, 0, 1), |
| 468 | rnd(o.seed()) { |
| 469 | if (opt.propagation() == PROP_UNARY) |
| 470 | nooverload(); |
| 471 | |
| 472 | // Number of jobs and machines/steps |
| 473 | int n = spec.jobs(), m = spec.machines(); |
| 474 | |
| 475 | fst.init(m*n*(n-1)/2); |
| 476 | snd.init(m*n*(n-1)/2); |
| 477 | |
| 478 | IntArgs jobs(m*n), dur(m*n); |
| 479 | |
| 480 | for (int i=0; i<n; i++) |
| 481 | for (int j=0; j<m; j++) { |
| 482 | jobs[spec.machine(i,j)*n+i] = i*m+j; |
| 483 | dur[spec.machine(i,j)*n+i] = spec.duration(i,j); |
| 484 | } |
| 485 | |
| 486 | int l=0; |
| 487 | for (int j=0; j<m; j++) { |
| 488 | for (int i1=0; i1<n; i1++) |
| 489 | for (int i2=i1+1; i2<n; i2++) { |
| 490 | if (dur[j*n+i1] > dur[j*n+i2]) { |
| 491 | order(*this, |
| 492 | start[jobs[j*n+i1]], dur[j*n+i1], |
| 493 | start[jobs[j*n+i2]], dur[j*n+i2], |
| 494 | sorder[l]); |
| 495 | fst[l] = j*n+i1; snd[l] = j*n+i2; |
| 496 | } else { |
| 497 | order(*this, |
| 498 | start[jobs[j*n+i2]], dur[j*n+i2], |
| 499 | start[jobs[j*n+i1]], dur[j*n+i1], |
| 500 | sorder[l]); |
| 501 | fst[l] = j*n+i2; snd[l] = j*n+i1; |
| 502 | } |
| 503 | l++; |
| 504 | } |
| 505 | assert(l == (j+1)*n*(n-1)/2); |
| 506 | } |
| 507 | |
| 508 | double tbf = opt.tbf(); |
| 509 | switch (opt.branching()) { |
| 510 | case BRANCH_AFC: |
| 511 | iafc.init(*this,start,opt.decay()); |
| 512 | if (tbf > 0.0) { |
| 513 | auto tbl = |
| 514 | [tbf] (const Space&, double w, double b) { |
| 515 | assert(b >= w); |
| 516 | return b - (b - w) * tbf; |
| 517 | }; |
| 518 | branch(*this, sorder, tiebreak(BOOL_VAR_MERIT_MAX(&afcmerit,tbl), |
| 519 | BOOL_VAR_RND(rnd)), |
| 520 | BOOL_VAL_MIN()); |
| 521 | } else { |
| 522 | branch(*this, sorder, BOOL_VAR_MERIT_MAX(&afcmerit), |
nothing calls this directly
no test coverage detected