One approach to modify the car painting example to handle the different setup times is to first create a data set:
data setup_time_data;
do from = 1 to 4;
do to = 1 to 4;
if from ne to then do;
if from = 1 and to = 3 then setup_time = 20;
else setup_time = 10;
output;
end;
end;
end;
run;
And then replace the IsPurge and ReifyCon declarations, as shown in the following code:
proc optmodel;
set CARS;
/* color of each car */
num car_color {CARS};
read data car_data into CARS=[_N_] car_color=color;
num nCars = card(CARS);
/* a car is identified by its original slots */
set SLOTS = CARS;
/* maximum reshuffling of any car on the line */
num maxMove init 3;
/* which car is in slot i */
var CarInSlot {i in SLOTS} integer
>= max(1, i - maxMove)
<= min(nCars, i + maxMove);
/* color of car in slot i */
num nColors = max {car in CARS} car_color[car];
var ColorInSlot {SLOTS} integer >= 1 <= nColors;
/* ColorInSlot[i] = car_color[CarInSlot[i]] */
con ElementCon {i in SLOTS}:
element(CarInSlot[i], car_color, ColorInSlot[i]);
/* each car can be painted only once */
con PaintOnlyOnce:
alldiff(CarInSlot);
set <num,num> PAIRS;
num setup_time {PAIRS};
read data setup_time_data into PAIRS=[from to] setup_time;
/* whether there is a purge after slot i, from color j to color k */
var IsPurge {SLOTS diff {nCars}, PAIRS} binary;
set COLORS = setof {car in CARS} car_color[car];
var IsColorInSlot {SLOTS, COLORS} binary;
con ReifyColor {i in SLOTS, c in COLORS}:
reify(IsColorInSlot[i,c], ColorInSlot[i] = c);
/* IsPurge[i,j,k] = 1 if and only if ColorInSlot[i] = j and ColorInSlot[i+1] = k */
con ReifyPurge {i in SLOTS diff {nCars}, <j,k> in PAIRS}:
reify(IsPurge[i,j,k], IsColorInSlot[i,j] + IsColorInSlot[i+1,k] = 2);
/* minimize the total time */
min TotalTime =
sum {i in SLOTS diff {nCars}, <j,k> in PAIRS} setup_time[j,k] * IsPurge[i,j,k];
/* call CLP solver */
solve;
/* write solution to data set */
create data car_ds from
{i in SLOTS} <col('S'||i)=CarInSlot[i]>
{i in SLOTS} <col('C'||i)=ColorInSlot[i]>;
quit;
The resulting optimal solution has objective value 50, with 5 purges, none of which are from red to green.
... View more