二、三维装箱简介
1 前言
三维装箱问题(Three Dimensional Container Loading Poblem)指在满足容积限制、外形几何限制和稳定性限制等条件的情况下,把一定数量体积较小的物品放入具有较大容量的一个或多个箱子,达到所用箱子数量最少、空间利用率最高、稳定性最好、装载价值最高、容重比最高等目的组合优化的问题。三维装箱问题广泛存在于运输和包装等行业的物资装载过程中,因此,如何针对实际应用需求设计具有较高操作性和装载效率的三维装箱求解算法,对于提高社会经济效益具有积极作用。
自20世纪60年代开始,三维装箱问题便因切割库存问题而提出,引起了学者关注,并被证明是具有较高复杂度的NP难问题。经过多年发展,三维装箱问题的求解不仅在枚举法、分支定界法等确定性算法上取得了进步。随着元启发式算法、遗传算法、粒子群算法等现代启发式算法的崛起,三维装箱问题的研究更加深入,逐步出现了带有多种现实约束和求解目标的复杂算法。其中,近年来具有代表性的相关研究如下所述。
Lodi等[9]受到一维装箱问题求解算法的启发,针对三维装箱问题提出了基于“先高后面积”(Height First-Area Second)的分层策略的结构式禁忌搜索算法,实验证明算法在分层堆放的情况下能得到较好的结果。Crainic等考虑了装载盒子时箱子剩余空间的描述和备选定位点的重要作用,为寻找每次装载时的合适空间位置和最优定位点,提出了极点(Extreme Points,EPS)的概念和计算方法,并设计了基于极点的三维装箱启发式算法。Karabulut[12]和Kang[13]等先后以规则长方体箱装载最大量规则长方体盒为研究目标,在设计深度、底部和左部方向优先装载(Deepest Bottom Left with Fill)物资装载策略的基础上,提出了基于遗传算法的三维装箱策略求解算法,2个研究的区别在于后者在前者的基础上,对装载剩余空间进行了更为细致的描述。Ramos等重点考虑了运输行业货物装载时静止时的纵向稳定性和行进时的横向稳定性,并提出了具有较高操作性的稳定性评价指标和基于顺序的货物装载启发式算法。
尽管三维装箱问题研究的深度和广度在不断延伸,相关研究的模型建立、算法设计和实际应用也取得了众多成果,但是一些现实约束仍难以满足,解决方法也存在较大的局限性。其中,现有求解三维装箱问题较为常用的遗传算法,在交叉算子设计、变异算子设计和进化性能等方面表现不足。
1 问题描述
1.1 基本问题描述
除球体、非规则立方体等形状盒子的装箱特例外,经典的三维装箱问题(见图1)可描述为:用一定数量的长宽高分别为Li,Wi和Hi的箱子(Container),按照一定顺序和装载规则根据不同转向逐个装入一定数量的长、宽、高分别为lj,wj和hj的盒子(Box)中,实现箱子容量的利用率最大、盒子堆放的稳定性最好、装载价值最高或容重比最恰当等其一或多种目标,并满足外形约束、容积约束、稳定性约束、盒子属性相关性约束、载重约束等实际限制。
图1 三维装箱问题示意
根据文献对三维装箱问题的分类法,该研究以SBSBPP类(Single Bin-Size Bin Packing Problem,有限数量单类型箱体三维装载问题)为研究对象,研究如何在单个规则长方体箱子中装载尽量多的盒子(这些盒子具有相似度较小且分散较大的特点),以最大限度地提高箱子的空间利用率。此研究旨在解决每个盒子应以何种顺序、何种方向放置在具体空间位置的问题,即提供具体的盒子装载方案。此过程需满足如下现实约束。
1)外形约束。进行装载时,所有盒子的几何顶点不能位于箱子之外,装进箱子的盒子在空间上不能发生重叠。
2)容积约束。装载盒子的总体积不能超过箱子的容积。
3)稳定性约束。装载盒子的堆放需满足重心要求,不能出现悬空或重心偏移的情况。
基本假设:盒子质量均匀分布,其质心位于其几何中心;不考虑盒子总质量超载的问题;盒子装载时应与箱子的边长方向平行(即不斜放)。
1.2 箱体最大剩余空间描述
最大剩余空间(Allowable Packing Area,简写为APA)指进行盒子装载前的最大长方体形闲置空间,每个最大剩余空间可用最靠近原点的长方体顶点三维坐标和最远离原点的长方体顶点三维坐标合并表示,全部的最大剩余空间即构成最大剩余空间集(简写为APAs)。盒子的装载是在箱子的最大剩余空间中按照一定规则进行的,最大剩余空间的刻画关系到盒子的放置和空间容纳能力,对于盒子的装载至关重要。该研究采用文献中的I-DBLF算法,完成最大剩余空间的描述。每装入一个箱子,其最大剩余空间将按照盒子的边界和x,y,z轴进行划分和更新。如图2a所示,空置箱子的最大剩余空间只有1个,表示为(0,0,0),(Li,Wi,Hi);在临原点位置装入一个长、宽、高分别为lj,wj和hj的盒子后,最大剩余空间更新为3个(见图2b—d),最大剩余空间集为{((Li-lj,0,0),(Li,Wi,Hi)),((0,0,Hi-hj),(Li,Wi,Hi)),((0,Wi-wj,0),(Li,Wi,Hi))}。最大剩余空间的计算过程较为复杂,因篇幅所限,此处不做赘述,具体可见文献。
图2 剩余空间示意
2 本案例代码说明
三维装箱:给定装载的四个约束:长,宽,高,限重,若干待装载货箱的信息:长,宽,高,重量,求满足约束的情况下,最佳的装载方式(或是达到最高载重,或是达到最大装载体积),以货物的装载顺序和在卡车中的位置表示。
求解思路:先把尺寸统一的货箱打包成合适的尺寸,以降低装载的复杂度。其次,设置策略为每个货箱选择合适的落脚点。最后,对多种装箱方式进行挑选,只对若干优秀的方式继续装填,舍弃劣解。
主程序 main (展示使用方法)
主装箱算法 final_zhuangxiang (整体框架)
对箱子进行分类打包 classification
对打包后的箱子及没打包的箱子进行装箱 zhuangxiang1
三、部分源代码
function [real_PATH,objective,surplus_box]=final_zhuangxiang(PATH,box,truck)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%函数名称:主装箱算法 final_zhuangxiang
%%入口参数:已装车的货物 PATH(cell格式,5行(左下坐标+信息+名称+名称+旋转方向)多列) 待装箱的货物信息 box(cell格式,第一行为长宽高重,第二行为货物的名称,第三行同第二行,第四行是旋转方向) 货车信息 truck
%%出口参数:装车的货物 real_PATH(格式同上述PATH) 当前车辆的优化目标 objective(max(v/V,w/W)) 未能装车的剩余货物 surplus_box
%%函数功能说明:
%%输入已装车的货物,未装车的货物,truck进行装车,步骤如下:
%%步骤1:打包
%%步骤2:对打包后的箱子+未打包的箱子进行装车
%%步骤3:解包
%%步骤4:评价
%%注意:
%%by SebastianLi, At ZhengZhou, 25th February, 2021
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 如果PATH不为空,并以剩余的空间作为约束进行打包,以防止打包过大
truck1=truck;
if isempty(PATH)==0
t=zeros(size(PATH,1),1);
num_PATH=1;
angles=[];
w=0;
for j=1:size(PATH{num_PATH, 1},1)
s=eightangle(PATH{num_PATH, 1}{j, 1},PATH{num_PATH, 1}{j, 2});
angles(end+1:end+8,:)=s;
w=w+PATH{num_PATH, 1}{j,2}(1,4);
end
truck1=[truck(1,1)-max(angles(:,1)),truck(1,2),truck(1,3),truck(1,4)-w]; % 只考虑x方向的剩余空间
end
%% 对于两种方向的箱子进行打包,取打包后箱子数小的打包方式作为最终打包
s2={};
for i=1:size(box,2)
s=box{1, i};
s1=[s(1, 2),s(1, 1),s(1, 3),s(1, 4)];
s2(1,i)={s1};
s2(2,i)=box(2, i);
end
s2(3,:)=s2(2, :);
s2(4,:)={0};
[Allbox1,~,~]=classification(s2,truck1); % 对全部旋转后的箱子进行分类打包
Allbox1(4,:)={1};
[Allbox2,~,~]=classification(box,truck1); % 对未旋转的箱子进行分类打包
Allbox2(4,:)={0};
if size(Allbox1,2)>=size(Allbox2,2) % 取打包后箱子数小的打包方式作为最终打包
Allbox=Allbox2;
y1=1;
else
Allbox=Allbox1;
y1=0;
end
%% 对打包后的箱子+未打包的箱子进行装车
s2={}; % 旋转后的Allbox
for i=1:size(Allbox,2)
s=Allbox{1, i};
s1=[s(1, 2),s(1, 1),s(1, 3),s(1, 4)];
s2(1,i)={s1};
s2(2,i)=Allbox(2, i);
s2(3,i)=Allbox(3, i);
s2(4,i)={y1};
if strcmp(Allbox{2,i}(1:3),'bag')==1
for j=1:size(s2{3,i},1)
s2{3,i}{j,1}=[s2{3, i}{j, 1}(1,2),s2{3, i}{j, 1}(1,1),s2{3, i}{j, 1}(1,3)];
s2{3,i}{j,2}=[s2{3, i}{j, 2}(1,2),s2{3, i}{j, 2}(1,1),s2{3, i}{j, 2}(1,3),s2{3, i}{j, 2}(1,4)];
end
end
end
Allbox=[Allbox,s2]; % 把旋转前后的箱子都放在一起
[final_PATH,~,surplus_box]=zhuangxiang1(PATH,Allbox,truck);
% show(final_PATH)
%% 把surplus_box中的bag拆分出来
if isempty(surplus_box)==0
ss={};
for i=1:size(surplus_box,2)
if strcmp(surplus_box{2,i}(1:3),'bag')==0 % 如果不是bag
if surplus_box{4,i}==0
ss(:,end+1)=[surplus_box(1,i);surplus_box(2,i)];
else
ss(:,end+1)=[{[surplus_box{1, i}(1,2),surplus_box{1, i}(1,1),surplus_box{1, i}(1,3),surplus_box{1, i}(1,4)]};surplus_box(2,i)];
end
else
if surplus_box{4,i}==0
for j=1:size(surplus_box{3,i},1)
ss(:,end+1)=[surplus_box{3,i}(j,2);surplus_box{3,i}(j,3)];
end
else
for j=1:size(surplus_box{3,i},1)
ss(:,end+1)=[{[surplus_box{3,i}{j,2}(1,2),surplus_box{3,i}{j,2}(1,1),surplus_box{3,i}{j,2}(1,3),surplus_box{3,i}{j,2}(1,4)]};surplus_box{3,i}(j,3)];
end
end
end
end
surplus_box=ss;
surplus_box(3,:)=surplus_box(2,:);
surplus_box(4,:)={0};
end
%% 拆分bag
if isempty(final_PATH)==1 % 如果所有的箱子都不能装车
real_PATH={};
objective=0;
else
real_PATH={}; % 把bag再拆分成箱子
for i=1:size(final_PATH{1, 1},1)
if strcmp(final_PATH{1, 1}{i, 3}(1:3),'bag')==0
real_PATH(end+1,:)=final_PATH{1, 1}(i,:);
end
if strcmp(final_PATH{1, 1}{i, 3}(1:3),'bag')==1
s=final_PATH{1, 1}{i, 4};
for j=1:size(final_PATH{1, 1}{i, 4},1)
s{j,1}=final_PATH{1, 1}{i, 4}{j, 1}+final_PATH{1, 1}{i, 1};
s{j,4}=s{j,3};
s{j,5}=0;
end
real_PATH(end+1:end+size(s,1),:)=s;
end
end
%% 评估货车的装载情况
v=0;
w=0;
for i=1:size(real_PATH,1)
v=v+real_PATH{i, 2}(1,1)*real_PATH{i, 2}(1,2)*real_PATH{i, 2}(1,3);
w=w+real_PATH{i, 2}(1,4);
end
V=truck(1,1)*truck(1,2)*truck(1,3);
W=truck(1,4);
objective=max(v/V,w/W);
end
四、运行结果
五、matlab版本及参考文献
1 matlab版本
2014a
2 参考文献
[1] 包子阳,余继周,杨杉.智能优化算法及其MATLAB实例(第2版)[M].电子工业出版社,2016.
[2]张岩,吴水根.MATLAB优化算法源代码[M].清华大学出版社,2017.
[3]周品.MATLAB 神经网络设计与应用[M].清华大学出版社,2013.
[4]陈明.MATLAB神经网络原理与实例精解[M].清华大学出版社,2013.
[5]方清城.MATLAB R2016a神经网络设计与应用28个案例分析[M].清华大学出版社,2018.