Originally posted by: PhilippeLaborie
Hi Andy,
I'm not sure why the transition matrix does not work for modelling this. You could say the transition distance between two consecutive Drop (two consecutive Pkup) is IntervalMax (or any large number). If your transition distance if posted to hold on direct successors only (noOverlap(seq, tdist, onDirect=1), then it will rule out the forbidden transitions.
But I'm not sure why you need this. I would suggest a model as follow (quite similar to the one proposed by Petr). For each job i:
job[i]: the job (present)
moveTo[i]: the moving activity (present) from the stocker to the machine of job i by a vehicle
moveFrom[i]: the moving activity (present) from the machine of job i to the stocker by a vehicle
jobOnMachine[i][m]: optional interval for job i on machine m
moveToMachine[i][m]: optional interval representing the moving activity from the stocker to the machine m of job i by a vehicle, size is given by the transition time from stocker to m
moveFromMachine[i][m]: optional interval representing the moving activity from the machine m of job i to the stocker by a vehicle, size is given by the transition time from m to the stocker
moveToMachineByVehicle[i][m][v]: optional interval representing the moving activity from the stocker to the machine m of job i by vehicle v
moveFromMachineByVehicle[i][m][v]: optional interval representing the moving activity from the machine m of job i to the stocker by vehicle v
then you have alternative constraints
alternative(job[i], [ all(m) jobOnMachine[i][m] ])
alternative(moveTo[i], [ all(m) moveToMachine[i][m] ])
alternative(moveToMachine[i][m], [ all(v) moveToMachineByVehicle[i][m][v] ])
alternative(moveFrom[i], [ all(m) moveFromMachine[i][m] ])
alternative(moveFromMachine[i][m], [ all(v) moveFromMachineByVehicle[i][m][v] ])
and precedence constraints:
endBeforeStart(moveTo[i], job[i])
endBeforeStart(job[i], moveFrom[i])
and logical constraints:
presenceOf(jobOnMachine[i][m]) == presenceOf(moveToMachine[i][m])
presenceOf(jobOnMachine[i][m]) == presenceOf(moveFromMachine[i][m])
and noOverlap:
forall(m) noOverlap( [ all(i) jobOnMachine[i][m] ])
forall(v) noOverlap( [ all(i,m) moveToMachineByVehicle[i][m][v], all(i,m) moveFromMachineByVehicle[i][m][v] ], TransitionDistance)
The idea of the model is to only model as interval variables the movements of the vehicles when they carry something, the movements when they are empty are just handled by transition times (no interval variable) in the transition distance. If you have M machine and thus, M+1 locations by including the stocker, you can pre-compute the transition distance for the noOverlap on vehicles using 2M types (as you have 2 kinds of intervals: the Stocker to Machine m ones and the machine m to Stocker ones).
#DecisionOptimization#OPLusingCPOptimizer