钢管下料问题

生产中常会遇到通过切割、剪裁、冲压等手段,将原材料加工成所需大小这种工 艺过程,称为原料下料(cutting stock)问题。按照进一步的工艺要求,确定下料方案, 使用料最省或利润最大,是典型的优化问题。本节通过一个实例讨论用数学规划模型解 决这类问题的方法。 另一个实例:易拉罐下料问题: 用数学建模优化生产管理问题 - CSDN博客

目录

问题描述

1.1  问题(1)的求解

1 问题分析

2 模型建立 

3 模型求解

1.2  问题(2)的求解 

(1)问题分析

(2)模型建立 

(3)模型求解


问题描述

某钢管零售商从钢管厂进货,将钢管按照顾客的要求切割后售出。从钢管厂 进货时得到的原料钢管都是 19m 长。

(1)现有一客户需要 50 根 4m 长,20 根 6m 长和 15 根 8m 长的钢管。应如何下 料最节省?

(2)零售商如果采用的不同切割模式太多,将会导致生产过程的复杂化,从而增 加生产和管理成本,所以该零售商规定采用的不同切割模式不能超过 3 种。此外,该客户除需要(1)中的三种钢管外,还需要 10 根 5m 长的钢管。应如何下料最节省?

1.1  问题(1)的求解

1 问题分析

首先,应当确定哪些切割模式是可行的。所谓一个切割模式,是指按照客户需要在原料钢管上安排切割的一种组合。例如,我们可以将 19m 长的钢管切割成 3 根 4m 长的钢管,余料为 7m;或者将 19m 长的钢管切割成 4m,6m 和 8m 长的钢管各 1 根, 余料为 1m。显然,可行的切割模式是很多的。

其次,应当确定哪些切割模式是合理的。通常假设一个合理的切割模式的余料不应该大于或等于客户需要的钢管的最小尺寸。例如,将 19m 长的钢管切割成 3 根 4m 的钢管是可行的,但余料为 7m,可以进一步将 7m 的余料切割成 4m 钢管(余料为 3m), 或者将 7m 的余料切割成 6m 钢管(余料为 1m)。在这种合理性假设下,切割模式一共 有 7 种,如表 3 所示。

表 3 钢管下料的合理切割模式
模式类别 4m钢管根数 6m钢管根数  8m钢管根数        余料(m)
模式 14003
模式 23101
模式 32013
模式 41203
模式 51111
模式 60301
模式 70023

问题化为在满足客户需要的条件下,按照哪些种合理的模式,切割多少根原料钢 管,最为节省。而所谓节省,可以有两种标准,一是切割后剩余的总余料量最小,二是 切割原料钢管的总根数最少。下面将对这两个目标分别讨论。

2 模型建立 

  •  决策变量:

x_{i } 表示按照第i种模式(i = 1 2,,,7)切割的原料钢管的根数,显然它们应当是非负整数。 决策目标:以切割后剩余的总余料量最小为目标,则由表 3 可得 

\textup{min}\: \: z_{1}=3x_{1}+x_{2}+3x_{3}+3x_{4}+x_{5}+x_{6}+3x_{7}              ( 1 )

以切割原料钢管的总根数最少为目标,则有       \textup{min} \: \: z_{2} =\sum_{i=1}^{7}x_{i}             ( 2 )

 

下面分别在这两种目标下求解。 约束条件:为满足客户的需求,按照表 3 应用 

          4x_{1} +3x_{2}+2x_{3} +x_{4}+x_{5}\geqslant 50\: ;\: \\ \; \; \; x_{2}+x_{4}+x_{5}+3x_{6}\geqslant 20\:                ( 3 )

      x_{3}+x_{5}+2x_{7}\geqslant 15                                               ( 4 )

3 模型求解

i)将式(1)和(3)构成的整数线性规划模型(加上整数约束)输入 LINGO 

model: 
TITLE 钢管下料-最小化余量; 
sets: col/1..7/:c,x; 
row/1..3/:b; 
link(row,col):a; 
endsets 
data: 
c=3 1 3 3 1 1 3; 
b=50 20 15; 
a=4 3 2 1 1 0 0   
    0 1 0 2 1 3 0   
    0 0 1 0 1 0 2; 
enddata 
min=@sum(col:c*x); 
@for(row(i):@sum(col(j):a(i,j)*x(j))>=b(i)); 
@for(col:@gin(x)); 
end

 求得按照模式 2 切割 12 根原料钢管,按照模式 5 切割 15 根原料钢管,共 27 根, 总余料量为 27m。但 4m 长的钢管比要求多切割了 1 根,6m 长的钢管比要求多切割了 7 根。显然,在总余料量最小的目标下,最优解将是使用余料尽可能小的切割方式(模 式 2 和模式 5 的余料为 1m),这会导致切割原料钢管的总根数较多。

ii)将式(2)~(4)构成的整数线性规划模型输入 LINGO 

model: 
TITLE 钢管下料-最小钢管数; 
sets: col/1..7/:c,x; 
row/1..3/:b; 
link(row,col):a; 
endsets 
data: 
c=3 1 3 3 1 1 3; 
b=50 20 15; 
a=4 3 2 1 1 0 0   
    0 1 0 2 1 3 0   
    0 0 1 0 1 0 2; 
enddata 
min=@sum(col:c*x); 
@for(row(i):[con1]@sum(col(j):a(i,j)*x(j))>=b(i)); 
@for(col:@gin(x)); 
[remainder]y=@sum(col:c0*x); 
end

求得按照模式 2 切割 15 根原料钢管,按模式 5 切割 5 根,按模式 7 切割 5 根,共 25 根,可算出总余料量为 35m。但各长度的钢管数恰好全部满足要求,没有多切割。 与上面得到的结果比较,总余料量增加了 8m,但是所用的原料钢管的总根数减少了 2 根。在余料没有什么用途的情况下,通常选择总根数最少为目标。 

1.2  问题(2)的求解 

(1)问题分析

按照问题(1)的思路,可以通过枚举法首先确定哪些切割模式是可行的。但由于需要的钢管规格增加到 4 种,所以枚举法的工作量较大。下面介绍的整数非线性规划模 型,可以同时确定切割模式和切割计划,是带有普遍性的方法。 同问题(1)类似,一个合理的切割模式的余料不应该大于或等于客户需要的钢管的最小尺寸(本题中为 4m),切割计划中只使用合理的切割模式,而由于本题中参数都 是整数,所以合理的切割模式的余量不能大于 3m。此外,这里我们仅选择总根数最少为目标进行求解。

(2)模型建立 

决策变量:由于不同切割模式不能超过 3 种,可以用 x_{j}  表示按照第 j 种模式(j=1,2,3 )切割的原料钢管的根数,显然它们应当是非负整数。设所使用的第 j 种切割模式下每根原料钢管生产 4m 长,5m 长,6m 长和 8m 长的钢管数量分别为
r_{1j}\: ,\: r_{2j},\: r_{3j}\: ,\: r_{4j} \:(非负整数)。记客户需求的 4 种钢管的长度为 l_{i}  ,所以l=\left ( 4,5,6,8 \right )\: ; 数量为 b_{i}( i =1,2,3,4 ),即\: b=\left ( 50,10,20,15 \right )

表4 三种钢管下料问题
  4m钢管根数 5m钢管根数 6m钢管根数 8m钢管根数 余料(m)
模式 1r_{11}r_{21}r_{31}r_{41}   \leqslant 3
模式 2r_{12}r_{22}r_{32}r_{42}\leqslant 3
模式 3r_{13}r_{23}r_{33}r_{43}\leqslant 3

决策目标:以切割原料钢管的总根数最少为目标,即目标为  \textup{min}\: \sum_{j=1}^{3}x_{j}           (  5 )

约束条件:为满足客户的需求,应有             \sum_{j=1}^{3}\: r_{ij}x_{j}\geqslant b_{i}\: ,\: i=1,2,3,4               ( 6 )

 每一种切割模式必须可行、合理,所以每根原料钢管的成品量不能超过 19m,也 不能少于 16m(余量不能大于 3m),于是 

16\: \leqslant \sum_{i=1}^{4}\: l_{i}r_{ij}\leqslant 19 \: ,j=1,2,3                                ( 7 )

 由于l=\left ( 4,5,6,8 \right )\: ; 所以  \sum_{i=1}^{4}\: l_{i}r_{ij}=l_{1}r_{1j}+l_{2}r_{2j}+l_{3}r_{3j}+l_{4}r_{4j}=4r_{1j}+5r_{2j}+6r_{3j}+8r_{4j}

有的小伙伴私信问我怎么用MATLAB实现它,其实就是把上面的式子(6)和(7)展开就好啦,也就是对于式子(6)有:

r_{11}x_{1} +r_{12}x_{2} +r_{13}x_{3} \geqslant 50    (4米的钢管需求为50根);

r_{21}x_{1} +r_{22}x_{2} +r_{23}x_{3} \geqslant 10    (5米的钢管需求为10根)

r_{31}x_{1} +r_{32}x_{2} +r_{33}x_{3} \geqslant 20    (6米的钢管需求为20根)

r_{41}x_{1} +r_{42}x_{2} +r_{43}x_{3} \geqslant 15    (8米的钢管需求为15根)


对于式子(7)有:

4r_{11}+5r_{21}+6r_{31}+8r_{41} \geqslant 164r_{12}+5r_{22}+6r_{32}+8r_{42} \geqslant 16 ;   4r_{13}+5r_{23}+6r_{33}+8r_{43} \geqslant 16

4r_{11}+5r_{21}+6r_{31}+8r_{41} \leqslant 19  ;   4r_{12}+5r_{22}+6r_{32}+8r_{42} \leqslant 19  ;  4r_{13}+5r_{23}+6r_{33}+8r_{43} \leqslant 19

(3)模型求解

式(5)~(7)构成这个问题的优化模型。由于在式(5)~(7)中出现了决 策变量的乘积,所以这是一个整数非线性规划模型,虽然用 LINGO 软件可以直接求解, 但我们发现有时 LINGO 软件运行很长时间也难以得到最优解。为了减少运行时间,可 以增加一些显然的约束条件,从而缩小可行解的搜索范围。

例如,由于 3 种切割模型的排列顺序是无关紧要的,所以不妨增加以下约束: x_{1 }\geqslant x_{2 }\geqslant x_{3 }       ( 8 )

又如,我们注意到所需原料钢管的总根数有着明显的上界和下界。首先,无论如何,原料钢管的总根数不可能少于              [ (  4*50+5*10+6*20+8*15 ) /19] = 26 (根)。其次,考虑一种非常特殊的生产计划:第一种切割模式下只生产 4m 钢管,1 根原料钢管切割 成 4 根 4m 钢管,为满足 50 根 4m 钢管的需求,需要 13 根原料钢管;第二种切割模式 下只生产 5m、6m 钢管,一根原料钢管切割成 1 根 5m 钢管和 2 根 6m 钢管,为满足 10 根 5m 钢管和 20 根 6m 钢管的需求,需要 10 根原料钢管;第三种切割模式下只生产 8m 钢管,1 根原料钢管切割成 2 根 8m 钢管,为满足 15 根 8m 钢管的需求,需要 8 根原料 钢管。于是满足要求的这种生产计划共需  13+10+8= 31 根原料钢管,这就得到了最 优解的一个上界。所以可增加以下约束:

 26\: \leqslant \sum_{i=1}^{3}\: x_{i} \leqslant 31\:          ( 9 )

  将式(5)~(9)构成的模型输入 LINGO 如下: 

model: 
Title 钢管下料 - 最小化钢管根数的LINGO模型; 
SETS:  
    NEEDS/1..4/: LENGTH,b;   
    CUTS/1..3/:X;          
    PATTERNS(NEEDS,CUTS):R;   
ENDSETS 
DATA:  
    LENGTH=4 5 6 8;  
    b=50 10 20 15;  
    CAPACITY=19; 
ENDDATA 
min=@SUM(CUTS(I): X(I) );    
@FOR(NEEDS(I):@SUM(CUTS(J):X(J)*R(I,J))>b(I) ); 
@FOR(CUTS(J):@SUM(NEEDS(I):LENGTH(I)*R(I,J))<CAPACITY );  @FOR(CUTS(J):@SUM(NEEDS(I):LENGTH(I)*R(I,J))>CAPACITY-@MIN(NEEDS(I): LENGTH(I)));             @SUM(CUTS(I):X(I))>26; @SUM(CUTS(I):X(I)) <31; !人为增加约束; @FOR(CUTS(I)|I#LT#@SIZE(CUTS):X(I)>X(I+1) ); !人为增加约束;     
@FOR(CUTS(J): @GIN(X(J))) ; 
@FOR(PATTERNS(I,J):@GIN(R(I,J))); 
end

得到按照模式 1,2,3 分别切割 10,10,8 根原料钢管,使用原料钢管总根数为 28 根。第一种切割模式下 1 根原料钢管切割成 2 根 4m 钢管、1 根 5m 钢管和 1 根 6m 钢管;第二种切割模式下 1 根原料钢管切割成 3 根 4m 钢管和 1 根 6m 钢管;第三种模 式下 1 根原料钢管切割成 2 根 8m 钢管。


对于问题2 的MATLAB求解方式,相当于有15个未知数。 由于没有等式约束,我们用空矩阵[ ]表示。我们采用fmincon函数求解最小值。有目标函数为:\textup{min}\:\: \: x_{1}+x_{2}+x_{3}

由于MATLAB中的线性不等式形如AX\leqslant b,所以有 【线性(不等式)约束】为

-x_{1}-x_{2}-x_{3} \leqslant -26

x_{1}+x_{2}+x_{3} \leqslant 31; 

-x_{1} +x_{2} \leqslant 0

-x_{2} +x_{3} \leqslant 0

-4r_{11}-5r_{21}-6r_{31}-8r_{41} \leqslant - 16

-4r_{12}-5r_{22}-6r_{32}-8r_{42} \leqslant - 16 ;

-4r_{13}-5r_{23}-6r_{33}-8r_{43} \leqslant - 16

4r_{11}+5r_{21}+6r_{31}+8r_{41} \leqslant 19  ;  

4r_{12}+5r_{22}+6r_{32}+8r_{42} \leqslant 19  ; 

4r_{13}+5r_{23}+6r_{33}+8r_{43} \leqslant 19

非线性(不等式)约束条件为

-r_{11}x_{1} -r_{12}x_{2} -r_{13}x_{3} +50 \leqslant 0 ; 

-r_{21}x_{1} -r_{22}x_{2} -r_{23}x_{3} +10 \leqslant 0   

-r_{31}x_{1} -r_{32}x_{2} -r_{33}x_{3} +20 \leqslant 0  ;

-r_{41}x_{1} -r_{42}x_{2} -r_{43}x_{3} +15 \leqslant 0   


所以求解的MATLAB代码如下,由于没有增加整数约束,导致求出来的结果是小数,还望大神在评论区告诉我怎么加整数约束。

 

clc
clear
%close all 

x0 =rand(15,1);  %15个未知数

fun =@(x)x(1)+x(2)+x(3); % 目标函数

%用x(4)、x(5)、x(6)表示r11 、r12 、r13
%用x(7)、x(8)、x(9)表示r21、 r22、 r23
%用x(10)、x(11)、x(12)表示r31 、r32 、r33 
%用x(13)、x(14)、x(15)表示r41 、r42 、r43

% c 为10个线性(不等式)约束,需要转换成小于等于0的形式
A= [-1 -1 -1 0 0 0 0 0 0 0 0 0 0 0 0;
    1 1 1 0 0 0 0 0 0 0 0 0 0 0 0; 
    -1 1 0 0 0 0 0 0 0 0 0 0 0 0 0;
    0 -1 1 0 0 0 0 0 0 0 0 0 0 0 0;
    0 0 0 -4 0 0 -5 0 0 -6 0 0 -8 0 0;
    0 0 0 0 -4 0 0 -5 0 0 -6 0 0 -8 0;
    0 0 0 0 0 -4 0 0 -5 0 0 -6 0 0 -8;
    0 0 0 4 0 0 5 0 0 6 0 0 8 0 0;
    0 0 0 0 4 0 0 5 0 0 6 0 0 8 0;
    0 0 0 0 0 4 0 0 5 0 0 6 0 0 8;
    ];

b = [-26;31;0;0;-16;-16;-16;19;19;19];

%c为非线性(不等式)约束,需要转换成小于等于0的形式
c=@(x)[ -x(1)*x(4)-x(2)*x(5)-x(3)*x(6) +50;
    -x(1)*x(7)-x(2)*x(8)-x(3)*x(9) +10;
    -x(1)*x(10)-x(2)*x(11)-x(3)*x(12) +20;
    -x(1)*x(13)-x(2)*x(14)-x(3)*x(15) +15;
    ];
nonlinfon = @(x)deal(c(x));
lb = [0;0;0;0;0;0;0;0;0;0;0;0;0;0;0] % 所有的x都大于等于0
%
options = optimoptions(@fmincon,'MaxIter',10000);
options=optimoptions(@fmincon,'MaxFunEvals',100000);
[x fval exitflag]  = fmincon(fun,x0,A,b,[],[],lb,[],nonlinfon,options)

 另外关于exitflag 为-1和-2说明没找到最优解;为1-5说明找到了(局部)最优解。为0是迭代次数很多但仍不收敛,可考虑修改最大迭代次数。

x =[   16.4649;    0.0001;    0.0000;

    0.1654;    1.1044;    1.0892
    0.2021;    0.8803;    0.9247
    0.2394;    0.7258;    0.7205
    0.3166;    0.5630;    0.5527 ].
fval =   16.4649
exitflag =     0

 

 

钢管下料问题可以通过使用Matlab求解。可以采用动态规划方法来建立模型,以最小化切割后的余料。在这个问题中,我们需要确定切割的模式和数量,以及切割后的余料最少。 首先,我们需要将问题转化为一个数学模型。我们可以将每根钢管的最小切割尺寸设定为6米(即客户需要的钢管的最小尺寸)。然后,我们可以定义一个决策变量,表示每个尺寸的钢管需要切割的数量。接下来,我们需要定义一个目标函数,即切割后的余料数量。最后,我们需要添加一些约束条件,如切割数量不能超过原始钢管的数量,切割后的余料尺寸不能小于客户需求的最小尺寸。 使用Matlab求解下料问题的代码示例如下: ```matlab % 定义参数 steel_length = 19; % 钢管长度 needed_lengths = [4, 6, 8]; % 客户需要的钢管长度 needed_quantities = [50, 20, 15]; % 客户需要的钢管数量 min_cut_size = 6; % 钢管的最小切割尺寸 % 定义决策变量 x = intvar(length(needed_lengths), 1); % 每个尺寸的钢管需要切割的数量 % 定义目标函数 objective = sum(x); % 定义约束条件 constraints = []; for i = 1:length(needed_lengths) constraints = [constraints, x(i)*needed_lengths(i) >= needed_quantities(i)*min_cut_size]; end constraints = [constraints, sum(x.*needed_lengths) <= steel_length]; % 定义优化问题 problem = optimproblem('Objective', objective, 'Constraints', constraints); % 求解优化问题 solution = solve(problem); % 输出结果 cut_quantities = solution.x; fprintf('钢管切割模式:\n'); for i = 1:length(needed_lengths) fprintf('%d米长的钢管:%d根\n', needed_lengths(i), cut_quantities(i)); end fprintf('切割后的余料最少:%d米\n', solution.objective); ``` 这段代码将给出钢管的切割模式以及切割后的余料最少数量。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值