一、简介
三维装箱:给定装载的四个约束:长,宽,高,限重,若干待装载货箱的信息:长,宽,高,重量,求满足约束的情况下,最佳的装载方式(或是达到最高载重,或是达到最大装载体积),以货物的装载顺序和在卡车中的位置表示。
求解思路:先把尺寸统一的货箱打包成合适的尺寸,以降低装载的复杂度。其次,设置策略为每个货箱选择合适的落脚点。最后,对多种装箱方式进行挑选,只对若干优秀的方式继续装填,舍弃劣解。
主程序 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
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
- 133.
- 134.