SETS
   i stages    / 1*5 /
   in(i) initial stage /1/
   af(i)  stages except initial one /2*5/
   j jobs / 1*15 /
   k machines / 1*5 /
   w due date set /1*15/
   n slots of machines  / 1*15 /
   jobstage(i,j)  stages of jobs /
$include input\jobstages.txt
/
   last(i,j) last stage of job j /
$include input\laststages.txt
/
   parmach(i,j,k) parallel machines in stage i of job j /
$include input\parallelmachine.txt
/
   t number of tardiness level / 1*3 /
;

ALIAS (j,r);
ALIAS (i,l);

PARAMETERS
   z(i,j)    no-wait stages/
$include input\nowait.txt
/
   d(j)      desired due date of jobs to be delivered to assembly line/
$include input\desiredduedate.txt
/
   rel(j)      release date of jobs from body shop/
$include input\release.txt
/
   p(i,j)    processing time of job j in stage i/
$include input\processing.txt
/
   fix(i,j)      if there is fixed machine assignment between stage i and i+1 of job j/
$include input\route.txt
/
   Du(w)      due dates /
$include input\duedateset.txt
/
   a(t)      upper bound on level t /
1        0
2        1
3        1000
/
   Co(t)      cost to tardiness at level t /
1        0
2        100
3        10000
/
;

SCALAR
   M a large positive number /1000/
   pen penalty /10000/
;

VARIABLES
   y(i,j,k,n)      machine assignment and sequence
   c(i,j)          completion time of job j at stage i
   mo(i,j)          move time of job j from stage i
   g(j,w)          due date assignment of job j
   Pa(j,t)         stepwise tardiness
   slack(j,w)      slack var
;

POSITIVE VARIABLES c,mo, slack  ;
binary variables y ;
binary VARIABLES Pa,g ;
FREE VARIABLES totcost;

EQUATIONS

   completion(i,j)      initial stage completion
   departure(i,j)       departure of jobs from stages
   zerobuffer(i,j)      zero buffer between stages
   nowait(i,j)          no-wait station constraint
   machineass(i,j)      machine assignment
   machineall(k,n)      machine allocation
   machineseq0(i,j,k,n,l,r)  machine sequencing
   machineseq(i,j,k,n,l,r)  machine sequencing
   slotseq1(k,n)    slot seq
   route(i,j,k,n)       machine dependence route
   duedate1(w)          due date assignment to each due date
   duedate2(j)          due date assignment to each job j
   tardiness(i,j,t)       stepwise tardiness
   tard_cor(j)          tardiness corridor for job j
   duedateass(i,j,w)      due date assignment
   objfunc              objective function
;


completion(i,j)$(in(i))..                                                      c(i,j) =g= rel(j) + p(i,j) ;
departure(i,j)$jobstage(i,j)..                                                 c(i,j) =l= mo(i,j) ;
zerobuffer(i,j)$(af(i) and jobstage(i,j))..                                    mo(i-1,j) + p(i,j) =e= c(i,j) ;
nowait(i,j)..                                                                  z(i,j)*(c(i,j)-mo(i,j)) =g= 0 ;
machineass(i,j)$(jobstage(i,j))..                                              sum(k$(parmach(i,j,k)),sum(n,y(i,j,k,n))) =e= 1 ;
machineall(k,n)..                                                              sum(j,sum(i$parmach(i,j,k),y(i,j,k,n))) =l= 1 ;
machineseq0(i,j,k,n,l,r)$(parmach(i,j,k) and not sameas (j,r) and ord(l)=1)..  M*(2-y(i,j,k,n)-y(l,r,k,n+1))+(rel(r)-mo(i,j)) =g= 0 ;
machineseq(i,j,k,n,l,r)$(parmach(i,j,k) and not sameas (j,r) and ord(l)>1)..   M*(2-y(i,j,k,n)-y(l,r,k,n+1))+(mo(l-1,r)-mo(i,j)) =g= 0 ;
slotseq1(k,n)..                                                                sum(j,sum(i$parmach(i,j,k),y(i,j,k,n))) =g= sum(j,sum(i$parmach(i,j,k),y(i,j,k,n+1))) ;
route(i,j,k,n)..                                                               b(i,j)*(y(i,j,k,n)-y(i+2,j,k,n)) =e= 0 ;
duedate1(w)..                                                                  sum(j,g(j,w)) =e= 1 ;
duedate2(j)..                                                                  sum(w,g(j,w)) =e= 1 ;
tardiness(i,j,t)$(last(i,j))..                                                 mo(i,j)-d(j) =l= a(t)+(1-Pa(j,t))*M ;
tard_cor(j)..                                                                  sum(t,Pa(j,t)) =e= 1 ;
duedateass(i,j,w)$(last(i,j))..                                                mo(i,j)-slack(j,w) =l= (1-g(j,w))*M + Du(w) ;
objfunc..                                                                      totcost =g= sum(j,sum(t,Co(t)*Pa(j,t))+sum(w,(pen*slack(j,w)))) ;


MODEL sequence / all /;

OPTION optCr = 0.1;
OPTION limrow = 10000;


SOLVE sequence using MIP minimizing totcost;

DISPLAY mo.l;
DISPLAY g.l, y.l, Pa.l, slack.l;
DISPLAY totcost.l;

file objresult /output\objvalue.txt/
put  objresult
put totcost.l
putclose  objresult

file assignment /output\assignment.txt/
put  assignment
loop(i,
loop(j,
loop(k,
      loop(n $(y.l(i,j,k,n) GT 0.5),
         put i.tl;
         put ".";
         put j.tl;
         put ".";
         put k.tl;
         put ".";
         put n.tl;
         put ".";
         put y.l(i,j,k,n)
         put /;
      ) )  )
    );
putclose  assignment

file comp /output\completion.txt/
put  comp
loop(i,
loop(j,
         put i.tl;
         put ".";
         put j.tl;
         put ".";
         put c.l(i,j)
         put /;
      )
    );
putclose  comp
file delivery /output\move.txt/
put  delivery
loop(i,
loop(j,
         put i.tl;
         put ".";
         put j.tl;
         put ".";
         put mo.l(i,j)
         put /;
      )
    );
putclose  delivery
file duedate /output\due.txt/
put  duedate
loop(j,
loop(w,
        put j.tl;
        put ".";
        put w.tl;
        put ".";
        put g.l(j,w)
        put /;
     )
   );
putclose  duedate
file stepwise /output\tardiness.txt/
put  stepwise
loop(j,
loop(t,
         put j.tl;
         put ".";
         put t.tl;
         put ".";
         put Pa.l(j,t)
         put /;
      )
    );
putclose  stepwise

file slackvar /output\slackv.txt/
put  slackvar
loop(j,
loop(w,
         put j.tl;
         put ".";
         put w.tl;
         put ".";
         put slack.l(j,w)
         put /;
      )
    );
putclose  slackvar
