例子来源于《数学规划模型建立与计算机应用》(第三版)[英]H.P.威廉斯中问题部分的题目。
工厂规划(1)
一机械厂用如下一些机床制造7种产品(PROD1~PROD7):4台磨床、2台立式钻床、3台卧式钻床、1台镗床、1台刨床。每件产品能获得一定的利润(售价减去原材料费,以镑/件计)。利润量(镑/件)连同每一种工艺过程需要的单位加工时间(以小时计)给出如下。表中横线表示该产品不必经过此道工序。
产品 |
PROD1 |
PROD2 |
PROD3 |
PROD4 |
PROD5 |
PROD6 |
PROD7 |
利润 |
10 |
6 |
8 |
4 |
11 |
9 |
3 |
研磨 |
0.5 |
0.7 |
— |
— |
0.3 |
0.2 |
0.5 |
立钻 |
0.1 |
0.2 |
— |
0.3 |
— |
0.6 |
— |
卧钻 |
0.2 |
— |
0.8 |
— |
— |
— |
0.6 |
镗孔 |
0.05 |
0.03 |
— |
0.07 |
0.1 |
— |
0.08 |
刨削 |
— |
— |
0.01 |
— |
0.05 |
— |
0.05 |
当前月份(一月)和以后的五个月份中有些机床需要停车维修。这些机床是:一月份1台磨床;二月份2台卧式钻床;三月份1台镗床;四月份1台立式钻床;五月份1台磨床和1台立式钻床;六月份1台刨床和一台卧式钻床。
各月份各种产品的市场销售限量如下:
产品 |
PROD1 |
PROD2 |
PROD3 |
PROD4 |
PROD5 |
PROD6 |
PROD7 |
一月 |
500 |
1000 |
300 |
300 |
800 |
200 |
100 |
二月 |
600 |
500 |
200 |
0 |
400 |
300 |
150 |
三月 |
300 |
600 |
0 |
0 |
500 |
400 |
100 |
四月 |
200 |
300 |
400 |
500 |
200 |
0 |
100 |
五月 |
0 |
100 |
500 |
100 |
1000 |
300 |
0 |
六月 |
500 |
500 |
100 |
300 |
1100 |
500 |
60 |
每种产品一次至多存储100件,每月存储费为0.5镑/件。目前无存货,但希望六月底时每种产品应有50件存货。
工厂一星期工作六天,每天两个班次,每班8小时。加工顺序可不必考虑。假设每月有24个工作日。
为使总利润最大,该厂应怎样安排产品生产时间和产品的品种?给出价格增长的建议和买进新机器的价值。
工厂规划(2)
求出每台机床停车维修的最佳月份以取代工厂规划(1)问题中规定的停车维修时间。
除磨床在半年内有两台需要停车维修外,其它每台机床在半年内的某个月份必须停车维修。
将该模型扩展,使其能够作出这些额外的决策。试问有多少时间允许作为额外停车维修的机动时间?
!LINGO代码; !工厂规划(1); model: ! profit -- 每件产品的利润,已知 time -- 每件产品在机床上的加工时间,已知 maxsell -- 产品在每月的最大销售量,已知 pro -- 每月生产的产品数量,待优化 mop -- 每种产品的一次最多的存储量,已知 startop -- 生产周期开始时各种产品的存货量,已知 endop -- 生产周期结束时各种产品的存货量,已知 sop -- 月末产品的存货量,待优化 sell -- 当月产品的销售量,待优化 amount -- 每月各类机器的数量,已知 ; sets: prod/1..7/:profit,mop,startop,endop; machine/1..5/; month/1..6/; table1(machine,prod):time; table2(month,prod):maxsell,pro,sop,sell; table3(month,machine):amount; endsets data: profit = 10 6 8 4 11 9 3; time= 0.5 0.7 0 0 0.3 0.2 0.5 0.1 0.2 0 0.3 0 0.6 0 0.2 0 0.8 0 0 0 0.6 0.05 0.03 0 0.07 0.1 0 0.08 0 0 0.01 0 0.05 0 0.05; maxsell = 500 1000 300 300 800 200 100 600 500 200 0 400 300 150 300 600 0 0 500 400 100 200 300 400 500 200 0 100 0 100 500 100 1000 300 0 500 500 100 300 1100 500 60; amount = 3 2 3 1 1 4 2 1 1 1 4 2 3 0 1 4 1 3 1 1 3 1 3 1 1 4 2 2 1 0; sc=0.5; !每件产品每月的存储费用; mop=100; startop=0; endop=50; enddata totalhour_month=24*8*2; !每月每台机器的工作时间,以小时为单位; totalmonth=@size(month); !月份总的个数; max=@sum(table2(I,J):profit(J)*sell(I,J)-sc*sop(I,J)); !产量、销售量和存储量(剩余量)三者之间的关系; @for(prod(J):startop(J)+pro(1,J)-sell(1,J)=sop(1,J);); !首月; @for(table2(I,J)|I #gt# 1: sop(I-1,J)+pro(I,J)-sell(I,J)=sop(I,J); ); !中间几个月; @for(prod(J): sop(totalmonth,J)=endop(J)); !末月; @for(table2: sell<=maxsell); !当月产品的销售量不超过当月市场的最大销售量; !每月每类机床应该提供足够的时间来生产产品; @for(month(I): @for(machine(J): [Con] @sum(prod(K): pro(I,K)*time(J,K))<=amount(I,J)*totalhour_month; ); ); !每种产品月末的存储量不能超限; @for(table2(I,J): sop(I,J)<=mop(J);); end
!LINGO代码; !工厂规划(2)问题1; model: ! profit -- 每件产品的利润,已知 time -- 每件产品在机床上的加工时间,已知 maxsell -- 产品在每月的最大销售量,已知 pro -- 每月生产的产品数量,待优化 mop -- 每种产品的一次最多的存储量,已知 startop -- 生产周期开始时各种产品的存货量,已知 endop -- 生产周期结束时各种产品的存货量,已知 sop -- 月末产品的存货量,待优化 sell -- 当月产品的销售量,待优化 amount -- 每月各类机器的数量,已知 ; sets: prod/1..7/:profit,mop,startop,endop; machine/1..5/:totalmachine,repairn; month/1..6/; table1(machine,prod):time; table2(month,prod):maxsell,pro,sop,sell; table3(month,machine):amount; endsets data: profit = 10 6 8 4 11 9 3; time= 0.5 0.7 0 0 0.3 0.2 0.5 0.1 0.2 0 0.3 0 0.6 0 0.2 0 0.8 0 0 0 0.6 0.05 0.03 0 0.07 0.1 0 0.08 0 0 0.01 0 0.05 0 0.05; maxsell = 500 1000 300 300 800 200 100 600 500 200 0 400 300 150 300 600 0 0 500 400 100 200 300 400 500 200 0 100 0 100 500 100 1000 300 0 500 500 100 300 1100 500 60; totalmachine=4 2 3 1 1; repairn=2 2 3 1 1; !amount = 3 2 3 1 1 4 2 1 1 1 4 2 3 0 1 4 1 3 1 1 3 1 3 1 1 4 2 2 1 0; sc=0.5; !每件产品每月的存储费用; mop=100; startop=0; endop=50; enddata totalhour_month=24*8; !每月每台机器的工作时间,以小时为单位; totalmonth=@size(month); !月份总的个数; max=@sum(table2(I,J):profit(J)*sell(I,J)-sc*sop(I,J)); !产量、销售量和存储量(剩余量)三者之间的关系; @for(prod(J):startop(J)+pro(1,J)-sell(1,J)=sop(1,J);); !首月; @for(table2(I,J)|I #gt# 1: sop(I-1,J)+pro(I,J)-sell(I,J)=sop(I,J); ); !中间几个月; @for(prod(J): sop(totalmonth,J)=endop(J)); !末月; @for(table2: sell<=maxsell); !当月产品的销售量不超过当月市场的最大销售量; !每月每类机床应该提供足够的时间来生产产品; @for(month(I): @for(machine(J): @sum(prod(K): pro(I,K)*time(J,K))<=amount(I,J)*totalhour_month; ); ); !每种产品月末的存储量不能超限; @for(table2(I,J): sop(I,J)<=mop(J);); @for(table3(I,J): amount(I,J)<=totalmachine(J);amount(I,J)>=totalmachine(J)-repairn(J); ); @for(machine(J): @sum(month(I): amount(I,J))=totalmonth*totalmachine(J)-repairn(J); ); @for(table3: @gin(amount)); end
!LINGO代码; !工厂规划(2)问题2; model: ! profit -- 每件产品的利润,已知 time -- 每件产品在机床上的加工时间,已知 maxsell -- 产品在每月的最大销售量,已知 pro -- 每月生产的产品数量,待优化 mop -- 每种产品的一次最多的存储量,已知 startop -- 生产周期开始时各种产品的存货量,已知 endop -- 生产周期结束时各种产品的存货量,已知 sop -- 月末产品的存货量,待优化 sell -- 当月产品的销售量,待优化 amount -- 每月各类机器的数量,已知 ; sets: prod/1..7/:profit,mop,startop,endop; machine/1..5/:totalmachine,repairn; month/1..6/; table1(machine,prod):time; table2(month,prod):maxsell,pro,sop,sell; table3(month,machine):amount; endsets data: profit = 10 6 8 4 11 9 3; time= 0.5 0.7 0 0 0.3 0.2 0.5 0.1 0.2 0 0.3 0 0.6 0 0.2 0 0.8 0 0 0 0.6 0.05 0.03 0 0.07 0.1 0 0.08 0 0 0.01 0 0.05 0 0.05; maxsell = 500 1000 300 300 800 200 100 600 500 200 0 400 300 150 300 600 0 0 500 400 100 200 300 400 500 200 0 100 0 100 500 100 1000 300 0 500 500 100 300 1100 500 60; totalmachine=4 2 3 1 1; repairn=2 2 3 1 1; !amount = 3 2 3 1 1 4 2 1 1 1 4 2 3 0 1 4 1 3 1 1 3 1 3 1 1 4 2 2 1 0; sc=0.5; !每件产品每月的存储费用; mop=100; startop=0; endop=50; enddata totalhour_month=24*8*2; !每月每台机器的工作时间,以小时为单位; totalmonth=@size(month); !月份总的个数; max=@sum(table2(I,J):profit(J)*sell(I,J)-sc*sop(I,J)); !产量、销售量和存储量(剩余量)三者之间的关系; @for(prod(J):startop(J)+pro(1,J)-sell(1,J)=sop(1,J);); !首月; @for(table2(I,J)|I #gt# 1: sop(I-1,J)+pro(I,J)-sell(I,J)=sop(I,J); ); !中间几个月; @for(prod(J): sop(totalmonth,J)=endop(J)); !末月; @for(table2: sell<=maxsell); !当月产品的销售量不超过当月市场的最大销售量; !每月每类机床应该提供足够的时间来生产产品; @for(month(I): @for(machine(J): [con] @sum(prod(K): pro(I,K)*time(J,K))<=amount(I,J)*totalhour_month; ); ); !每种产品月末的存储量不能超限; @for(table2(I,J): sop(I,J)<=mop(J);); @for(table3(I,J): amount(I,J)<=totalmachine(J);amount(I,J)>=totalmachine(J)-repairn(J); ); @for(machine(J): @sum(month(I): amount(I,J))=totalmonth*totalmachine(J)-repairn(J); ); @for(table3: @gin(amount)); end