钢管下料问题
某钢管零售商从钢管厂进货,将钢管按照顾客的要求切割后售出,从钢管厂进货时得到的原料钢管都是19m 。
(1)现在一客户需要50根4m 、20根6m 和15根8m 的钢管。
应如何下料最节省?
(2) 零售商如果采用的不同切割模式太多,将会导致生产过程的复杂化,从而增加生产和管理成本,所以该零售商规定采用的不同切割模式不能超过3种。
此外,该客户除需要(1)中的三种钢管外,还需要10根5m 的钢管。
应如何下料最节省。
问题(1)分析与模型建立
首先分析1根19m 的钢管切割为4m 、6m 、8m 的钢管的模式,所有模式相当于求解不等式方程:
12346819k k k ++≤
的整数解。
但要求剩余材料12319(468)4r k k k =-++<。
容易得到所有模式见表1。
决策变量 用i x 表示按照第i 种模式(i=1,2,…,7)切割的原料钢管的根数。
以切割原料钢管的总根数最少为目标,则有
1234567min z x x x x x x x =++++++ 约束条件 为满足客户的需求,4米长的钢管至少50根,有 1236743250x x x x x ++++≥ 6米长的钢管至少20根,有 25673220x x x x +++≥ 8米长的钢管至少15根,有 346215x x x ++≥ 因此模型为:
1234567min z x x x x x x x =++++++
123672567
346432503220..215,1,2,,7
i x x x x x x x x x s t x x x x i ++++≥⎧⎪+++≥⎪⎨
++≥⎪⎪=⎩取整 解得:
12345670,12,0,0,0,15,0x x x x x x x =======
目标值z=27。
即12根钢管采用切割模式2:3根4m ,1根6m ,余料1m 。
15根钢管采用切割模式6:1根4m ,1根6m ,1根8m ,余料1m 。
切割模式只采用了2种,余料为27m ,使用钢管27根。
LINGO 程序:
model: sets:
model/1..7/:x; endsets
min=x(1)+x(2)+x(3)+x(4)+x(5)+x(6)+x(7); 4*x(1)+3*x(2)+2*x(3)+x(6)+x(7)>=50; x(2)+3*x(5)+x(6)+2*x(7)>=20; x(3)+2*x(4)+x(6)>=15; @for(model(i):@gin(x(i))); end
问题(2)模型建立
首先分析1根19m 的钢管切割为4m 、6m 、8m 、5m 的钢管的模式,所有模式相当于求解不等式方程: 1234468519k k k k +++≤
的整数解。
但要求剩余材料12319(468)4r k k k =-++<。
利用Matlab 程序求出所有模式见表2。
求出所有模式的Matlab 程序: number=0; for k1=0:4 for k2=0:3 for k3=0:2 for k4=0:3
r=19-(4*k1+6*k2+8*k3+5*k4); if(r>=0)&(r<4)
number=number+1;
fprintf('%2d %2d %2d %2d %2d %2d\n',number,k1,k2,k3,k4,r); end
end end end end
表2 钢管切割模式
决策变量 用i x 表示按照第i 种模式(i=1,2,…,16)切割的原料钢管的根数。
决策目标 以切割原料钢管的总根数最少为目标,则有 16
21
min i i z x ==
∑
设第i 种切割模式下4米长的钢管i a 根,6米长的钢管i b 根,8米长的钢管i c 根,5米长的钢管i d 根。
则约束条件有:
为满足客户的需求,4米长的钢管至少50根,有
16
150i i
i a x
=≥∑
6米长的钢管至少20根,有
16
1
20i i
i b x
=≥∑
8米长的钢管至少15根,有
16
115i i
i c x
=≥∑
5米长的钢管至少10根,有
16
1
10i i
i d x
=≥∑
为实现最多使用3种切割模式,增设0-1变量,1,2,
,16i y i =。
当0i y =时,0i x =,表示不使用第i 种切割模式;当1i y =时,1i x ≥,表示使用第i 种切割模式。
因此有:
i i x y ≥,.i i x M y ≤,1,2,,16i =
其中M 足够大,如这里取100。
16
1
3i
i y
=≤∑
因此模型为:
16
1
min i i z x ==∑
16
116
116
116
1
16
1
50201510...,1,2,,16,1,2,,163,1,2,,1601,1,2,,16i i i i i i i i i i i i i i i i i i i
i a x b x c x d x s t x M y i x y i y x i y i M =====⎧≥⎪⎪⎪≥⎪⎪⎪≥⎪⎪⎪≥⎪⎨⎪≤=⎪
≥=⎪⎪⎪≤⎪⎪=⎪⎪==⎪
⎩∑∑∑∑∑取整或足大
解得:
当所用钢管z 最少时,求得的解为:
213158,10,10x x x ===,其余为0。
目标值z=28。
即8根钢管采用切割模式2:2根8m,余料3m。
10根钢管采用切割模式13:2根4m,1根6m,1根5m,余料为0。
10根钢管采用切割模式15:3根4m,1根6m,余料1m。
切割模式采用了3种,余料为34,使用钢管z=28根。
LINGO程序为:
model:
sets:
model/1..16/:a,b,c,d,r,x,y;
endsets
data:
a=0,0,0,0,0,0,1,1,1,1,2,2,2,3,3,4;
b=0,0,1,1,2,3,0,0,1,2,0,0,1,0,1,0;
c=1,2,0,1,0,0,0,1,1,0,0,1,0,0,0,0;
d=2,0,2,1,1,0,3,1,0,0,2,0,1,1,0,0;
r=1,3,3,0,2,1,0,2,1,3,1,3,0,2,1,3;
enddata
min=z;
z1=@sum(model(i):r(i)*x(i));!余料;
z=@sum(model(i):x(i));!钢管总数;
@sum(model(i):a(i)*x(i))>=50;!4米长钢管约束;
@sum(model(i):b(i)*x(i))>=20;!6米长钢管约束;
@sum(model(i):c(i)*x(i))>=15;!8米长钢管约束;
@sum(model(i):d(i)*x(i))>=10;!5米长钢管约束;
@for(model(i):x(i)>=y(i));
@for(model(i):x(i)<=1000*y(i));
@sum(model(i):y(i))<=3;
@for(model(i):@gin(x(i)));
@for(model(i):@bin(y(i)));
end。