2022华为杯数学建模B题——方形件组批优化问题

本文记录了参与2022华为杯数学建模比赛的经验,强调提交文件格式要求。作者参考了矩形排样问题的相关论文,并提供了使用MATLAB实现的层次聚类算法,用于订单的组批优化,以解决方形件的批量生产问题。代码包括数据处理、聚类分析及不满足约束条件的簇识别过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文章用于记录2022华为杯数学建模B题——方形件组批优化问题
提醒:大家最终提交的时候记得是pdf文件,不是word文件。
第一次参加建模比赛,经验不足,准备不充分,能力也欠缺。考虑2023年继续再战!

经过查询,发现该问题与以下两篇论文较为相似,我们的工作也是基于此开展的。
[1]严玄. 矩形三阶段带排样问题的遗传算法的研究[D].广西师范大学,2009.
[2]张浩. 面向板式产品定制生产的组批与排样协同优化方法[D].广东工业大学,2019.

下面提供我们所写文章的链接。
链接: 文章

下面为个人用MATLAB编写的层次聚类算法。
代码:

Clustering.m

clc,clear;
%读取path对应的.csv文件的数据
csv_data=readmatrix('csv_change.csv');        

%确定X矩阵的大小,并赋0值
for i=1:length(csv_data)
    a=csv_data(i,1);
    b=csv_data(i,6);
    X(a,b)=0;
end
%为第a个订单编号的第b类材料计数
for i=1:length(csv_data)
    a=csv_data(i,1);
    b=csv_data(i,6);
    X(a,b)=X(a,b)+1;
end


%%%%    针对以上数据,开展层次聚类算法的研究

%获取距离矩阵
%X=randn(10,2);

Y=pdist(X);  
%获取聚类,第二参数指定层次聚类方式
Z=linkage(Y,'ward');

%画图
figure
%指定显示数量,0代表全部显示;颜色阈值100
H = dendrogram(Z,0,'ColorThreshold',100);

title('层次聚类法聚类结果');
%set(H,'linewidth',2);   %设置线的宽度
ylabel('欧式距离');
saveas(H,'层次聚类法聚类结果.Tif');


%%%%%   针对聚类结果Z开展**组批优化**研究

%计算初始簇Cu的N(产品数量,第一个)与S(产品面积,第二个)
for i=1:length(csv_data)
    a=csv_data(i,1);
    Cu_NS(a,1)=0;
    Cu_NS(a,2)=0;
end
for i=1:length(csv_data)
    a=csv_data(i,1);
    Cu_NS(a,1)=Cu_NS(a,1)+1;
    Cu_NS(a,2)=Cu_NS(a,2)+csv_data(i,5);
end

%%%%    开始组合簇 
% 不考虑约束条件
n=length(Z);

for i=1:n
    a=Z(i,1);b=Z(i,2);
    %求合并簇后对应的数量N、面积S
    Cu_NS(n+i,1)=0;
    Cu_NS(n+i,2)=0;
    Cu_NS(n+i,1)=Cu_NS(a,1)+Cu_NS(b,1);%数量
    Cu_NS(n+i,2)=Cu_NS(a,2)+Cu_NS(b,2);%面积
    %
%     Cu_Num(i,1)=i;
%     Cu_Num(n+i,1)=0;
%     
%     Cu_Num(n+i,end+1)=a;
%     Cu_Num(n+i,end+1)=b;
end
%每个簇对应的子簇(初始簇,最底层)
n=length(Z);
for i=1:n
    Cu_Num(i,1)=i;
    Cu_Num(n+i,n)=0;
end

for i=1:n
    a=Z(i,1);b=Z(i,2);
    aa=Cu_Num(a,:); aa(find(aa==0))=[];
    bb=Cu_Num(b,:); bb(find(bb==0))=[];
    cc=cat(2,aa,bb);
    for j=1:length(cc)
        Cu_Num(n+i,j)=cc(1,j);
    end

%     for j=1:length(aa)
%         %Cu_Num(n+i,j)=aa(1,j);
%     end
end
%每个簇对应的子簇(前2个,最近层)
n=length(Z);
for i=1:n
    a=Z(i,1);b=Z(i,2);
    Cu_in(i,1)=i;
    Cu_in(n+i,1)=n+i;
    Cu_in(n+i,2)=a;
    Cu_in(n+i,3)=b;
end
%找到不满足约束条件的全部簇群Cu_all
n=length(Cu_in);
j=1;
for i=1:n
    a=Cu_in(i,1);
    if Cu_NS(a,1) >1000 || Cu_NS(a,2) >250000000
        Cu_all(j,1)=a;
        j=j+1;
    end
end
%找到不满足约束条件的底层簇Cu_min
n=length(Cu_all);
j=1;
for i=1:n
    a=Cu_all(i,1);
    b=ismember(Cu_in(a,2),Cu_all);
    c=ismember(Cu_in(a,3),Cu_all);
    if b+c==0
        Cu_min(j,1)=a;
        j=j+1;
    end
end

csv_change.m

clc;
clear;
%拼接路径,读入all文件名
filename=dir('.\子问题2-数据集B\*.csv');
path=strcat('.\子问题2-数据集B\',filename(1).name);  

%读取path对应的.csv文件的数据
t=readcell(path);        
%删除第一行
t(1,:)=[]; 
%将订单编号进行排序,并转为数值导入到D中
order=erase(t(:,6),'order');
order_num=str2num(char(order));
[a,b]=sort(order_num); 

for i=1:length(a)
    D(i,1)=a(i);                    %D(:,1)代表订单编号
    D(i,2)=cell2mat(t(b(i),1));     %D(:,2)代表订单id
    w=cell2mat(t(b(i),4));
    D(i,3)=w;                       %D(:,3)代表订单宽度
    h=cell2mat(t(b(i),5));
    D(i,4)=h;                       %D(:,4)代表订单高度
    D(i,5)=w*h;                     %D(:,5)代表订单面积
end

%将材料类型按顺序赋值给D
[mat,mat_id]=sort(t(:,2));
m=1;
n=length(mat);
mat(n+1)=mat(n);

for i = 1:n
    for j =1:n
        if b(j)==mat_id(i)
            D(j,6)=m;               %D(:,6)代表材料类型
        end
    end
   
    if strcmp(mat(i),mat(i+1))==0
        m=m+1;        
    end
end

csvwrite('csv_change.csv',D);

Order_group_batch.m

clc;
clear all;
%拼接路径,读入all文件名
filename=dir('.\子问题2-数据集B\*.csv');
path=strcat('.\子问题2-数据集B\',filename(1).name);  

%读取path对应的.csv文件的数据
t=readcell(path);        
%删除第一行
t(1,:)=[]; 
%将订单编号进行排序,并转为数值导入到D中

for i=1:length(t)
    t(i,7)=num2cell(i);             %补充订单的排列顺序编号
end
order=erase(t(:,6),'order');

order_num=str2num(char(order));
[a,b]=sort(order_num); 

for i=1:length(a)
    D(i,1)=a(i);                    %D(:,1)代表订单编号
    D(i,2)=cell2mat(t(b(i),1));     %D(:,2)代表订单id
    D(i,7)=cell2mat(t(b(i),7));     %D(:,7)代表订单的排列顺序编号
    w=cell2mat(t(b(i),4));
    D(i,3)=w;                       %D(:,3)代表订单宽度
    h=cell2mat(t(b(i),5));
    D(i,4)=h;                       %D(:,4)代表订单高度
    D(i,5)=w*h;                     %D(:,5)代表订单面积
    
end

%将材料类型按顺序赋值给D
[mat,mat_id]=sort(t(:,2));
m=1;
n=length(mat);
mat(n+1)=mat(n);

for i = 1:n
    for j =1:n
        if b(j)==mat_id(i)
            D(j,6)=m;               %D(:,6)代表材料类型   数值
        end
    end
    if strcmp(mat(i),mat(i+1))==0
        m=m+1;        
    end
end

amax=max(D(:,1));
bmax=max(D(:,6));
X=zeros(amax,bmax);

%X为第a个订单编号的第b类材料计数
%XX为第a个订单编号所包含的产品顺序编号
n=length(D);

for i=1:n
    a=D(i,1);
    b=D(i,6);
    X(a,b)=X(a,b)+1;
end
w=1;

D(end+1,1)=0;
for i=1:length(D)-1
    a=D(i,1);
    b=D(i+1,1);
    XX(D(i,1),w)=D(i,7);
    if a==b
            w=w+1;
    else
            w=1;
    end
end
D(end,:)=[];

%%%%    针对以上数据,开展层次聚类算法的研究

%获取距离矩阵
%X=randn(10,2);

Y=pdist(X);  
%获取聚类,第二参数指定层次聚类方式
Z=linkage(Y,'ward');

%画图
figure(1)
%指定显示数量,0代表全部显示;颜色阈值100
%H = dendrogram(Z,0,'ColorThreshold',100);
H = dendrogram(Z,0);

title('层次聚类法聚类结果');
%set(H,'linewidth',2);   %设置线的宽度
ylabel('欧式距离');
saveas(1,'层次聚类法聚类结果.tif');


%%%%%   针对聚类结果Z开展**组批优化**研究


%计算初始簇Cu的N(产品数量,第一个)与S(产品面积,第二个)
Cu_NS=zeros(amax,2);
for i=1:length(D)
    a=D(i,1);
    Cu_NS(a,1)=Cu_NS(a,1)+1;
    Cu_NS(a,2)=Cu_NS(a,2)+D(i,5);
end

%%%%    开始组合簇 
% 不考虑约束条件
n=length(Z)+1;

for i=1:n-1
    a=Z(i,1);b=Z(i,2);
    %求合并簇后对应的数量N、面积S
    Cu_NS(n+i,1)=0;
    Cu_NS(n+i,2)=0;
    Cu_NS(n+i,1)=Cu_NS(a,1)+Cu_NS(b,1);%数量
    Cu_NS(n+i,2)=Cu_NS(a,2)+Cu_NS(b,2);%面积
    
end
%每个簇对应的子簇(初始簇,最底层)Cu_Num
n=length(Z)+1;
for i=1:n
    Cu_Num(i,1)=i;
    
end
for i=1:n-1
    Cu_Num(n+i,n)=0;
end

for i=1:n-1
    a=Z(i,1);b=Z(i,2);
    aa=Cu_Num(a,:); aa(find(aa==0))=[];     %删除数组末尾的0
    bb=Cu_Num(b,:); bb(find(bb==0))=[];
    cc=cat(2,aa,bb);                        %合并数组
    for j=1:length(cc)
        Cu_Num(n+i,j)=cc(1,j);
    end
end
%每个簇对应的子簇(前2个,最近层)Cu_in
n=length(Z)+1;
for i=1:n-1
    a=Z(i,1);b=Z(i,2);
    Cu_in(i,1)=i;
    Cu_in(n,1)=n;
    Cu_in(n+i,1)=n+i;
    Cu_in(n+i,2)=a;
    Cu_in(n+i,3)=b;
end
%找到不满足约束条件的全部簇群Cu_all
n=length(Cu_in);
j=1;
for i=1:n
        if Cu_NS(i,1) >1000 || Cu_NS(i,2) >250000000
        Cu_all(j,1)=i;
        j=j+1;
    end
end
%找到不满足约束条件的底层簇Cu_min
n=length(Cu_all)+1;
j=1;
for i=1:n-1
    a=Cu_all(i,1);
    b=ismember(Cu_in(a,2),Cu_all);  
    c=ismember(Cu_in(a,3),Cu_all);
    if b==0
        Cu_min(j,1)=Cu_in(a,2);
        j=j+1;
    end
    if c==0
        Cu_min(j,1)=Cu_in(a,3);
        j=j+1;
    end
end

%XX为产品顺序号D(:,7)
n=length(Cu_min);
w=2;
d(1,1)=0;
for i=1:n                   %遍历所有分类批次
    a=Cu_min(i);            %i批对应的簇
    b=Cu_Num(a,:);          %簇中包含的使用订单号
    b(find(b==0))=[];       %去末尾的零
    for j=1:length(b)       %遍历所有订单号
        c=XX(b(1,j),:);     %订单中包含的所有产品
        c(find(c==0))=[];
        d=cat(2,d,c);
        
    end
    for k=1:length(d)
        Cu_a(i,k)=d(1,k);
    end
    d=[];
    
end



%生成目标表格
strs1=[1;2];
strs2={'5-0218S';'5-0218S'};
strs3=[1;1];
strs4=[1;2];    strs5=[1;2];
strs6=[1;2];    strs7=[1;2];    strs8=[1;2];  strs9=[1;1];

Goals=table(strs1,strs2,strs3,strs4,strs5,strs6,strs7,strs8,strs9,...
    'VariableNames',{'批次序号',	'原片材质',	'原片序号',	'产品id',	...
    '产品x坐标',    '产品y坐标',	'产品x方向长度',	'产品y方向长度','原片材质_数字',});

n=length(Cu_min);
w=1;

for i=1:n                   %遍历同一批次下所有的产品顺序号D(:,7)
    a=Cu_a(i,:);  
    a(find(a==0))=[];       %去末尾的零
    for j=1:length(a)       %遍历所有产品顺序号
        for k=1:length(D)   %遍历所有数据
            if D(k,7)==a(j) %找寻相同产品顺序号
                Goals.("批次序号")(w)=i;
                Goals.("原片材质")(w)=t(D(k,7),2);
                Goals.("原片序号")(w)=0;
                Goals.("产品id")(w)=D(k,2);
                Goals.("产品x坐标")(w)=0;
                Goals.("产品y坐标")(w)=0;
                Goals.("产品x方向长度")(w)=D(k,3);
                Goals.("产品y方向长度")(w)=D(k,4);
                Goals.("原片材质_数字")(w)=D(k,6);

                w=w+1;

            end
        end
    end
end

%csvwrite('Goals.csv',Goals);

下图为层次聚类算法结果图:
在这里插入图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值