! Cutting stock model in LINGO (cutsgen)
with credit given for modest overage
of certain finished good sizes. We enumerate
different patterns for cutting each size of
raw material, and then determine how many
copies to run of each pattern so as to:
a) Minimize net cost of rm used,
b) do not use more rm than is available,
c) produce at least as much as is required
of each fg;
! Keywords: cutting stock, remnant inventory;
SETS:
! Each raw material has a size, quantity, and cost;
rm: lenr, qr, cr;
! Each finished good has a size, min quantity
needed, max quantity useful, and value of excess;
fg: lenf, qf, qful, valul, uexcess;
ENDSETS DATA:
! Describe the raw materials available;
rm, lenr, qr, cr =
R72 72 9999 28
R48 48 9999 19
R36 36 9999 15;
! Describe the finished goods needed.
We must produce at least qf units of each fg.
For any amount we produce above qf
up to qful, we get credit valul/unit;
fg, lenf, qf , qful, valul=
F60 60 500 500 0
F56 56 400 400 0
F42 42 300 300 0
F38 38 450 450 0
F34 34 350 350 0
F24 24 100 100 0
F15 15 800 800 0
F10 10 1000 1000 0;
ENDDATA
SETS:
! Enumerate all possible cutting patterns with 1 fg;
rxf(rm,fg)| lenf(&2) #le# lenr(&1): x1, w1;
! Enumerate all possible patterns with 2 fg;
rxf2( rxf, fg) | &2 #le# &3 #and# (lenf(&2) + lenf(&3) #le# lenr(&1)): x2,w2;
! Enumerate all possible patterns with 3 fg;
rxf3( rxf2, fg)| &3 #le# &4 #and# (lenf(&2) + lenf(&3)+ lenf(&4) #le# lenr(&1)): x3,w3;
! Enumerate all possible patterns with 4 fg;
rxf4( rxf3, fg)| &4 #le# &5 #and# (lenf(&2) + lenf(&3)+ lenf(&4)+lenf(&5)
#le# lenr(&1)): x4,w4;
! Enumerate all possible patterns with 5 fg;
rxf5( rxf4, fg)| &5 #le# &6 #and# (lenf(&2) + lenf(&3)+ lenf(&4)+lenf(&5)+lenf(&6)
#le# lenr(&1)): x5,w5;
! Enumerate all possible patterns with 6 fg;
rxf6( rxf5, fg)| &6 #le# &7 #and# (lenf(&2) + lenf(&3)+ lenf(&4)+lenf(&5)
+lenf(&6)+lenf(&7) #le# lenr(&1)): x6,w6;
! Enumerate all possible patterns with 7 fg;
rxf7( rxf6, fg)| &7 #le# &8 #and# (lenf(&2) + lenf(&3)+ lenf(&4)+lenf(&5)
+lenf(&6)+lenf(&7)+lenf(&8) #le# lenr(&1)): x7,w7;
! We assume that no cutting pattern need include more than 7 pieces;
ENDSETS
! Minimize cost of material used;
MIN = @SUM( rxf(r,f1): cr(r)*x1(r,f1))
+ @SUM( rxf2(r,f1,f2): cr(r)*x2(r,f1,f2))
+ @SUM( rxf3(r,f1,f2,f3): cr(r)*x3(r,f1,f2,f3))
+ @SUM( rxf4(r,f1,f2,f3,f4): cr(r)*x4(r,f1,f2,f3,f4))
+ @SUM( rxf5(r,f1,f2,f3,f4,f5): cr(r)*x5(r,f1,f2,f3,f4,f5))
+ @SUM( rxf6(r,f1,f2,f3,f4,f5,f6): cr(r)*x6(r,f1,f2,f3,f4,f5,f6))
+ @SUM( rxf7(r,f1,f2,f3,f4,f5,f6,f7): cr(r)*x7(r,f1,f2,f3,f4,f5,f6,f7))
! minus credit for overage that is not too huge;
- @SUM( fg( f): valul(f)*uexcess( f));
! We cannot use more of each raw material type r, than is available;
@FOR( rm( r):
@SUM(rxf(r,f): x1(r,f))
+ @SUM(rxf2(r,f1,f2): x2(r,f1,f2))
+ @SUM(rxf3(r,f1,f2,f3): x3(r,f1,f2,f3))
+ @SUM(rxf4(r,f1,f2,f3,f4): x4(r,f1,f2,f3,f4))
+ @SUM(rxf5(r,f1,f2,f3,f4,f5): x5(r,f1,f2,f3,f4,f5))
+ @SUM(rxf6(r,f1,f2,f3,f4,f5,f6): x6(r,f1,f2,f3,f4,f5,f6))
+ @SUM(rxf7(r,f1,f2,f3,f4,f5,f6,f7): x7(r,f1,f2,f3,f4,f5,f6,f7))
<= qr(r);
);
! We have to satisfy each finished good demand;
@FOR( fg(f):
[dem] @SUM(rxf(r,f): x1(r,f))
+ @SUM(rxf2(r,f1,f2)| f #eq# f1: x2(r,f1,f2))
+ @SUM(rxf2(r,f1,f2)| f #eq# f2: x2(r,f1,f2))
+ @SUM(rxf3(r,f1,f2,f3)| f #eq# f1: x3(r,f1,f2,f3))
+ @SUM(rxf3(r,f1,f2,f3)| f #eq# f2: x3(r,f1,f2,f3))
+ @SUM(rxf3(r,f1,f2,f3)| f #eq# f3: x3(r,f1,f2,f3))
+ @SUM(rxf4(r,f1,f2,f3,f4)| f #eq# f1: x4(r,f1,f2,f3,f4))
+ @SUM(rxf4(r,f1,f2,f3,f4)| f #eq# f2: x4(r,f1,f2,f3,f4))
+ @SUM(rxf4(r,f1,f2,f3,f4)| f #eq# f3: x4(r,f1,f2,f3,f4))
+ @SUM(rxf4(r,f1,f2,f3,f4)| f #eq# f4: x4(r,f1,f2,f3,f4))
+ @SUM(rxf5(r,f1,f2,f3,f4,f5)| f #eq# f1: x5(r,f1,f2,f3,f4,f5))
+ @SUM(rxf5(r,f1,f2,f3,f4,f5)| f #eq# f2: x5(r,f1,f2,f3,f4,f5))
+ @SUM(rxf5(r,f1,f2,f3,f4,f5)| f #eq# f3: x5(r,f1,f2,f3,f4,f5))
+ @SUM(rxf5(r,f1,f2,f3,f4,f5)| f #eq# f4: x5(r,f1,f2,f3,f4,f5))
+ @SUM(rxf5(r,f1,f2,f3,f4,f5)| f #eq# f5: x5(r,f1,f2,f3,f4,f5))
+ @SUM(rxf6(r,f1,f2,f3,f4,f5,f6)| f #eq# f1: x6(r,f1,f2,f3,f4,f5,f6))
+ @SUM(rxf6(r,f1,f2,f3,f4,f5,f6)| f #eq# f2: x6(r,f1,f2,f3,f4,f5,f6))
+ @SUM(rxf6(r,f1,f2,f3,f4,f5,f6)| f #eq# f3: x6(r,f1,f2,f3,f4,f5,f6))
+ @SUM(rxf6(r,f1,f2,f3,f4,f5,f6)| f #eq# f4: x6(r,f1,f2,f3,f4,f5,f6))
+ @SUM(rxf6(r,f1,f2,f3,f4,f5,f6)| f #eq# f5: x6(r,f1,f2,f3,f4,f5,f6))
+ @SUM(rxf6(r,f1,f2,f3,f4,f5,f6)| f #eq# f6: x6(r,f1,f2,f3,f4,f5,f6))
+ @SUM(rxf7(r,f1,f2,f3,f4,f5,f6,f7)| f #eq# f1: x7(r,f1,f2,f3,f4,f5,f6,f7))
+ @SUM(rxf7(r,f1,f2,f3,f4,f5,f6,f7)| f #eq# f2: x7(r,f1,f2,f3,f4,f5,f6,f7))
+ @SUM(rxf7(r,f1,f2,f3,f4,f5,f6,f7)| f #eq# f3: x7(r,f1,f2,f3,f4,f5,f6,f7))
+ @SUM(rxf7(r,f1,f2,f3,f4,f5,f6,f7)| f #eq# f4: x7(r,f1,f2,f3,f4,f5,f6,f7))
+ @SUM(rxf7(r,f1,f2,f3,f4,f5,f6,f7)| f #eq# f5: x7(r,f1,f2,f3,f4,f5,f6,f7))
+ @SUM(rxf7(r,f1,f2,f3,f4,f5,f6,f7)| f #eq# f6: x7(r,f1,f2,f3,f4,f5,f6,f7))
+ @SUM(rxf7(r,f1,f2,f3,f4,f5,f6,f7)| f #eq# f7: x7(r,f1,f2,f3,f4,f5,f6,f7))
>= qf(f) + uexcess(f);
! Cannot claim credit for huge amount of excess;
uexcess(f) <= qful(f) - qf(f);
);
! Can only run integer quantities of each pattern;
@FOR(rxf: @GIN(x1));
@FOR(rxf2: @GIN(x2));
@FOR(rxf3: @GIN(x3));
@FOR(rxf4: @GIN(x4));
@FOR(rxf5: @GIN(x5));
@FOR(rxf6: @GIN(x6));
@FOR(rxf7: @GIN(x7));
! Compute leftover of each pattern just for curiousity;
@FOR( rxf( r, f1):
w1(r,f1) = lenr( r) - lenf(f1);
);
@FOR( rxf2(r,f1,f2):
w2(r,f1,f2) = lenr(r) - lenf(f1) - lenf(f2);
);
@FOR( rxf3(r,f1,f2,f3):
w3(r,f1,f2,f3) = lenr(r) - lenf(f1) - lenf(f2)- lenf(f3);
);
@FOR( rxf4(r,f1,f2,f3,f4):
w4(r,f1,f2,f3,f4) = lenr(r) - lenf(f1) - lenf(f2)- lenf(f3) - lenf(f4);
);
@FOR( rxf5(r,f1,f2,f3,f4,f5):
w5(r,f1,f2,f3,f4,f5) = lenr(r)-lenf(f1)-lenf(f2)-lenf(f3)-lenf(f4)-lenf(f5);
);
@FOR( rxf6(r,f1,f2,f3,f4,f5,f6):
w6(r,f1,f2,f3,f4,f5,f6) = lenr(r)-lenf(f1)-lenf(f2)-lenf(f3)-lenf(f4)-lenf(f5)-lenf(f6);
);
@FOR( rxf7(r,f1,f2,f3,f4,f5,f6,f7):
w7(r,f1,f2,f3,f4,f5,f6,f7) =
lenr(r)-lenf(f1)-lenf(f2)-lenf(f3)-lenf(f4)-lenf(f5)-lenf(f6)-lenf(f7);
);
|