! 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); );