本文章用于记录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);
下图为层次聚类算法结果图: