1. 程式人生 > 其它 >【三維裝箱】基於matlab求解三維裝箱優化問題【含Matlab原始碼 949期】

【三維裝箱】基於matlab求解三維裝箱優化問題【含Matlab原始碼 949期】

一、簡介

三維裝箱:給定裝載的四個約束:長,寬,高,限重,若干待裝載貨箱的資訊:長,寬,高,重量,求滿足約束的情況下,最佳的裝載方式(或是達到最高載重,或是達到最大裝載體積),以貨物的裝載順序和在卡車中的位置表示。
求解思路:先把尺寸統一的貨箱打包成合適的尺寸,以降低裝載的複雜度。其次,設定策略為每個貨箱選擇合適的落腳點。最後,對多種裝箱方式進行挑選,只對若干優秀的方式繼續裝填,捨棄劣解。
主程式 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

 

三、執行結果

四、備註

版本:2014a
完整程式碼或代寫加1564658423