! Single Machine Job Selection and Sequencing.
Given a
Set of jobs, each with an
earliest begin time,
latest finish time,
processing time, and
value if processed, and a
machine that can process only one job at a time,
and changeover times between jobs,
Decide
which jobs to accept, and the
sequence in which to process accepted jobs;
! Keywords: Changeover times, Due dates, Job selection, Machine sequencing,
Scheduling, Sequence dependent setups, Sequencing, Setup time;
SETS:
!Parameters:
r( k) = earliest allowed start time of job k,
d( k) = latest allowed finish time of job k,
p( k) = processing time of job k,
cot( i, k) = changeover time from job i to k,
v( k) = value of job k,
Variables:
y( i, k) = 1 if both jobs i and k are accepted and
job i immediately precedes job k, else 0,
s( k) = start time of job k,
drop( k) = 1 if we do not do job k,
y0( k) = 1 if job k is first,
yL( k) = 1 if job k is last;
job: r, p, d, v, s, y0, yL, drop;
jxj( job, job): COT, y;
ENDSETS
DATA:
! 1 2 3 4 5 6 7 8 9 10 11 12
! Ready times;
r = 0 0 2 2 3 5 5 6 12 20 20 21;
! The processing times;
p = 18 24 4 8 13 1 12 2 3 6 5 5;
! Due date of each job;
d = 22 25 8 11 29 10 25 14 16 29 32 31;
! Value of processing the job;
v = 2 6 4 2 3 5 7 4 4 3 1 6;
! Change over time matrix;
COT= 0 1 3 2 1 2 5 3 2 1 1 1
2 0 2 3 5 1 2 2 0 3 2 1
3 4 0 3 4 2 1 1 2 1 4 1
1 1 3 0 4 1 2 1 1 3 3 1
2 3 2 3 0 3 5 3 2 2 2 1
4 1 2 1 4 0 2 2 4 3 2 4
5 0 2 3 4 4 0 3 4 3 0 4
1 2 2 3 1 1 2 0 4 4 2 4
2 0 2 2 4 2 3 3 0 3 1 4
2 1 2 3 4 1 2 3 4 0 2 4
2 0 2 3 4 0 2 3 4 3 0 4
4 1 1 1 1 1 3 3 3 3 4 0
;
ENDDATA
SUBMODEL JOBROUTE:
! Maximize the value of accepted jobs;
MAX = OBJ ;
OBJ = @SUM( job( j): v( j)*(1- DROP( j)));
! For each JOB k...;
@FOR( JOB( k):
! A job cannot follow itself...;
y( k, k) = 0;
! it must be either the first job, or preceded by some
other job i, or not done;
[NTR] y0( k) + @SUM( JOB( i)| i #NE# k : y( i, k)) + DROP( k) = 1;
! it must be either the last job, or followed by some
other job j, or not done;
[XIT] yL( k) + @SUM( JOB( j)| j #NE# k : y( k, j)) + DROP( k) = 1;
);
! There can be only one job that is...;
@SUM( JOB( k): y0( k)) <= 1; ! ... first;
@SUM( JOB( k): y0( k)) = @SUM( JOB( k): yL( k)); ! ... last;
! Make the y's binary, 0 or 1;
@FOR( jxj( j, k): @BIN( y( j, k)));
! Compute time at which job k starts;
@FOR( JOB( k):
@FOR( JOB( i) | i #NE# k:
! Time of start of job k if preceding job was i;
[RTM] s( k) >= s( i) + ( p( i) + COT( i, k))* y( i, k)
+ ( r( k) - d( i) + p( i))*(1- y( i, k)); ! otherwise;
);
s( k) >= r( k); ! Not early;
s( k) + p( k) <= d( k); ! Not late. Assume r( k) + p( k) <= d( k);
);
ENDSUBMODEL
CALC:
@SET( 'TERSEO', 2); ! Make default output terse;
@SET( 'IPTOLR', .01); ! Relative optimality tolerance;
@SET( 'TIM2RL', 30); ! Time to turn on IPTOLR in seconds;
@SOLVE( JOBROUTE);
! Display a little report;
@WRITE(' Which jobs should we do, in what order to Max Profit,',@NEWLINE(1),
' taking into account ready, changeover(COT), processing, & due times?',
@NEWLINE(1));
@WRITE(@NEWLINE(1),' Various times', @NEWLINE(1));
@WRITE(' Job Ready Processing Due Value COT Start Finish ',@NEWLINE(1));
@FOR( job( i):
@WRITE( @FORMAT( i,"3.0f"),' ', @FORMAT(r( i),"3.0f") ,' ', @FORMAT(p( i),"3.0f"),
' ', @FORMAT(d( i) ,"3.0f"),' ', @FORMAT(v( i),"3.0f"));
@IFC( drop( i) #LT# 0.5:
cotij = @SUM( job( k): cot( k, i)*y( k, i));
@WRITE(' ',@FORMAT( cotij, "3.0f"), ' ', @FORMAT( s( i),"3.0f"),
' ', @FORMAT( s( i)+ p( i),"3.0f"),@NEWLINE(1));
@ELSE
@WRITE(' -- -- --',@NEWLINE(1))
);
);
@WRITE(@NEWLINE(1),' Total value of accepted jobs= ',OBJ, @NEWLINE(1));
ENDCALC
|