【Matlab】模拟退火+最低水平线解决物流上的二维装箱问题

2023-05-16

        这里的装箱问题和我们在算法意义上的装箱问题不是一个概念!也就是不同于下面这篇博客里的装箱问题。

【C++】2018华为软挑:模拟退火+贪心FF解决装箱问题_玛丽莲茼蒿的博客-CSDN博客本文的主要工作是补充这篇博客的缺失代码,使之能够运行。2018华为软挑--模拟退火+FF解决装箱问题【C++代码】_小马哥MAX的博客-CSDN博客算法简介:装箱问题是一个NP完全问题,求解全局最优解有很多种方法:遗传算法、禁忌搜索算法、蚁群算法、模拟退火算法等等,本次使用模拟退火,它的优点是在参数合适的情况下基本上可以100%得到全局最优解,缺点是相较于其他算法,其稳定速度较慢。如果你对退火的物理意义还是晕晕的,没关系我们还有更为简单的理解方式。想象一下如果我们现在有下...https://blog.csdn.net/qq_44886213/article/details/124209211?spm=1001.2014.3001.5502

一、二维装箱问题描述

        只有一个固定长、宽的箱子。我们有多个不同长、宽的物体。求解是否有一个方案能把物体全部放进去,并且求解最省空间的方法。

二、完整代码

2.1 主程序调用及模拟退火部分

clear 
clc    %%清空环境变量
 
%  
%            可以读取不同的母板尺寸数据以及待排样矩形件的尺寸数量 
% 
Yuanliao=[25,21];       %设定母板长度和宽度 
BC=xlsread('pakagexls.xls','sheet2'); %读取数据
starttime=cputime; 

p=size(BC,1);%size(BC,1)返回矩阵BC的行数,size(BC,2)返回列数
cc=randperm(p);     %产生一个初始下料序列
 
xx=[zeros(p,1)';-ones(p,1)']; %生成一个第一行全 0,第二行全-1 的矩阵后面交换所用 
plot([0,Yuanliao(1),Yuanliao(1),0,0],[0;0;Yuanliao(2);Yuanliao(2);0],'--*b');   %绘制原料板
 
tic;
hold on; 
rate0=1;   
c0=cc; 
x0=xx(1,:); 
best=1; 
t0=1000;             %初始温度 
tf=1;                %结束温度 
dt=0.9; 
nk=200;              %最大迭代次数 200 
 
% for kk=1:5           %循环 5 次,为了使得到的解真是最优的
tk=t0; 
while tk>tf 
     %%%   进入内循环,内循环 200 次
 
     for k=1:nk 
         c=cc; 
         x=xx; 
         jjj=floor(p*rand+1);     %  产生一个邻域是的解
         iii=floor(p*rand+1);     %%% 
         kk=floor(p*rand+1); 
         a=c(iii); 
         c(iii)=c(jjj); 
         c(jjj)=a; 
         x(:,kk)=[x(2,kk);x(1,kk)];   %交换被选中的列的第一行和第二行,从而控制下料的横放竖放
         [rate,~]=LOW(BC,c,x(1,:),Yuanliao,0);%调用 LOW 函数进行下料的排序返回剩料率,调用函数中 0 是负责画图的选项0 表示不画图1 表示画图
 
         df=exp(-(rate-rate0)/tk); 
         if rate>rate0 
             df=exp(-(rate-rate0)/tk); 
             if df>rand 
                 cc=c; 
                 xx=x; 
                 rate0=rate; 
             end 
         else 
             cc=c; 
             xx=x; 
             rate0=rate; 
         end 
         if rate0<best   %%   更新历史最优值
 
             best=rate0; 
             c0=cc; 
             x0=xx; 
         end 
     end 
     tk=tk*dt; 
end 
disp('箱子总数p');
p
time=cputime-starttime
toc
% end 
[rate,R]=LOW(BC,c0,x0(1,:),Yuanliao,1)   %利用求的最优解调用 LOW 函数,输出最优剩料率,R 为最后的水平线。并画图。
 

 注意,箱子(母板)的长宽信息通过代码设置,物体的数据通过excel文件读取。在excel文件中有两列,第一列是长第二列是宽。如下图

2.2 核心函数部分

function [rate,R]=LOW(BC,c,x,Yuanliao,ifplot) 
downloaded_pakage_num=0; %统计放了多少个箱子
p=size(BC,1); 
R=[0,0,Yuanliao(1),0]; 
for i=1:p 
     if i==1 
         if x(c(i))==-1 
             BC(c(i),:)=[BC(c(i),2),BC(c(i),1)]; 
         end 
         R=[R(1),BC(c(i),2),BC(c(i),1),BC(c(i),2);... 
             BC(c(i),1),R(2),R(3),R(2)]; 
  S(i,:)=BC(c(i),:); 
         if ifplot==1 
             plot([0,S(i,1),S(i,1),0,0],[0,0,S(i,2),S(i,2),0]) 
             hold on; 
             downloaded_pakage_num=downloaded_pakage_num+1; %!!!!!!!
         end 
     end 
     if i~=1 
         if x(i)==-1 
             BC(c(i),:)=[BC(c(i),2),BC(c(i),1)]; 
         end 
         k=find(R(:,2)==min(R(:,2))); 
         [~,k]=sort(R(:,2)); 
         n=size(R,1); 
         S(i,:)=BC(c(i),:); 
         for ii=1:size(k,1) 
             if  ((R(k(ii),3)-R(k(ii),1))==BC(c(i),1))&&((Yuanliao(2)- R(k(ii),2))>BC(c(i),2)||(Yuanliao(2)-R(k(ii),2))==BC(c(i),2)) %------------------
                
                    R(k(ii),:)=[R(k(ii),1),BC(c(i),2)+R(k(ii),2),BC(c(i),1)+R(k(ii),1),BC(c(i),2)+R(k(ii),2)]; 
                 if ifplot==1 
                     plot([R(k(ii),1),R(k(ii),3),R(k(ii),3),R(k(ii),1),R(k(ii),1)],... 
                         [R(k(ii),2)-S(i,2),R(k(ii),2)- S(i,2),R(k(ii),4),R(k(ii),4),R(k(ii),2)-S(i,2)]) 
                     hold on; 
                     downloaded_pakage_num=downloaded_pakage_num+1; %!!!!!!!
                 end 
                 break; 
             elseif  ((R(k(ii),3)-R(k(ii),1))>BC(c(i),1))&&((Yuanliao(2)- R(k(ii),2))>BC(c(i),2)||(Yuanliao(2)-R(k(ii),2))==BC(c(i),2)) 
                 R(n+1,:)=[BC(c(i),1)+R(k(ii),1),R(k(ii),2),R(k(ii),3),R(k(ii),4)] ; 
                
                 R(k(ii),:)=[R(k(ii),1),BC(c(i),2)+R(k(ii),2),BC(c(i),1)+R(k(ii),1),BC(c(i),2)+R(k(ii),2)]; 
                 if ifplot==1 
                     plot([R(k(ii),1),R(k(ii),3),R(k(ii),3),R(k(ii),1),R(k(ii),1)],... 
                         [R(k(ii),2)-S(i,2),R(k(ii),2)-S(i,2),R(k(ii),4),R(k(ii),4),R(k(ii),2)-S(i,2)]) 
                     hold on; 
                     downloaded_pakage_num=downloaded_pakage_num+1; %!!!!!!!
                 end 
                 break; 
             end 
             if  ((R(k(ii),3)-R(k(ii),1))==BC(c(i),2))&&((Yuanliao(2)-R(k(ii),2))>BC(c(i),1)||(Yuanliao(2)-R(k(ii),2))==BC(c(i),1)) %------------------
                
R(k(ii),:)=[R(k(ii),1),BC(c(i),1)+R(k(ii),2),BC(c(i),2)+R(k(ii),1),BC(c(i),1)+R(k(ii),2)]; 
                 if ifplot==1 
                     plot([R(k(ii),1),R(k(ii),3),R(k(ii),3),R(k(ii),1),R(k(ii),1)],... 
                         [R(k(ii),2)-S(i,1),R(k(ii),2)-S(i,1),R(k(ii),4),R(k(ii),4),R(k(ii),2)-S(i,1)]) 
                     hold on; 
                     downloaded_pakage_num=downloaded_pakage_num+1; %!!!!!!!
                 end 
                 break; 
             elseif  ((R(k(ii),3)-R(k(ii),1))>BC(c(i),2))&&((Yuanliao(2)-R(k(ii),2))>BC(c(i),1)||(Yuanliao(2)-R(k(ii),2))==BC(c(i),1)) 
                 R(n+1,:)=[BC(c(i),2)+R(k(ii),1),R(k(ii),2),R(k(ii),3),R(k(ii),4)] ; 
                
R(k(ii),:)=[R(k(ii),1),BC(c(i),1)+R(k(ii),2),BC(c(i),2)+R(k(ii),1),BC(c(i),1)+R(k(ii),2)]; 
                 if ifplot==1 
 plot([R(k(ii),1),R(k(ii),3),R(k(ii),3),R(k(ii),1),R(k(ii),1)],... 
                         [R(k(ii),2)-S(i,1),R(k(ii),2)-S(i,1),R(k(ii),4),R(k(ii),4),R(k(ii),2)-S(i,1)]) 
                     hold on; 
                     downloaded_pakage_num=downloaded_pakage_num+1; %!!!!!!!
                 end 
                 break; 
             end 
         end 
         b=unique(R(:,2)); 
         if size(b,1)~=size(R(:,2),1) 
             for i=1:size(b,1) 
                 t=find(R(:,2)==b(i)); 
                 if size(t,1)~=1 
                     for ii=1:size(t,1)-1 
                         if (R(t(ii),3)==R(t(ii+1),1))||(R(t(ii),1)==R(t(ii+1),3)) 
                             SS=[min(R(t(ii),1),R(t(ii+1),1)),R(t(ii),2),... 
                                 max(R(t(ii),3),R(t(ii+1),3)),R(t(ii),2)]; 
                             R(t(ii+1),:)=SS; 
                             R(t(ii),:)=0; 
                         end 
                     end 
                 end 
             end 
         end 
         R(all(R==0,2),:)=[]; 
     end 
end 
Area=0; 
for i=1:size(R,1) 
     Area=Area+(R(i,3)-R(i,1))*(Yuanliao(2)-R(i,4)); 
end 
rate=Area/(Yuanliao(1)*Yuanliao(2)); 
downloaded_pakage_num %输出一共放好了多少箱子

2.3 运行结果解析

为了方便看懂,对其中某些结果进行解释:

1. 最低水平线

我们用虚线画出了最低水平线。

 输出的结果R应该是离最低水平线最近的物体的坐标,图中我写的“最低水平线的坐标”是不对的,不想改了。这个R应该一行一行的看,每一行由:x1,y1;x2,y2组成,把(x1,y1)和(x2,y2)连起来便是一条线。

2. 剩余率

先说容积率,箱子的容积率所有物体的面积除以箱子最低水平线下的面积。用1减去容积率便是剩余率,越小越好。

3.CPU运行时间

用两种方法给出了CPU运行时间,一般以第二种为准。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Matlab】模拟退火+最低水平线解决物流上的二维装箱问题 的相关文章

  • 这是 `min` 和 `nanmin` 之间的区别; Matlab 中的“max”和“nanmax”?

    Matlab描述nanmin and nanmax像这样 NANMIN最小值 忽略NaNs NANMAX最大值 忽略NaNs 但实际上 min and max ignore NaNs too 那我应该使用哪个 根据我的测试 nanmin a
  • 整数的十进制表示形式中的分隔数字

    例如 我想将用户输入作为整数输入 45697 并将前两位数字存储在数组 向量或其他内容中 例如 4 5 6 9 7 这样我就可以使用一些函数调用来检查前两个值 4 5 并对它们进行计算 问题 我不知道如何存储恢复前两个值 有没有简单的函数调
  • 作为动画的八度情节点

    我有以下八度脚本 TOTAL POINTS 100 figure 1 for i 1 TOTAL POINTS randX rand 1 randY rand 1 scatter randX randY hold on endfor 当我运
  • 单元格的 Fieldnames 函数的等效项

    正如标题所说 只是想知道是否有一个函数可以用作字段名 http www mathworks co uk help matlab ref fieldnames html 但适用于单元格 所以如果我有类似的东西 a imread redsqua
  • 为什么 MATLAB 在打印大量 (.png) 图形时速度会变慢?

    我正在将大量数字打印为 png 文件 每个图都是数据矩阵中的一列图 我获取 png 文件并将它们串在一起形成动画 我的问题是 前几百张图像打印得很快 但创建每个新图形的时间却迅速增加 从前几百个 png 文件的约 0 2 秒到第 800 个
  • 从 Java 运行 MATLAB 函数

    我在 MATLAB 中有一个 m 文件 我想从 Java 调用该文件 并以字符串或 Java 中的任何形式获取解决方案 这听起来很简单 但由于某种原因我无法让它发挥作用 我试过这个 matlab nosplash wait nodeskto
  • 如何每次使用按钮将数据添加到 MATLAB 中的现有 XLSX 文件?

    我有一个函数可以生成一些变量 例如分数 对 错 未回答 使用按钮调用此功能 问题是如何每次将函数生成的这些值添加 附加到 XLSX 文件中 或者 如何创建 MAT 文件以便可以添加它 可能的解决方案是什么 附加到 xls 文件所涉及的挑战是
  • MATLAB - GUI 和 OPC 服务器

    我想在 MATLAB 中设计一个图形用户界面 可以使用 MATLAB 的过程控制对象链接和嵌入 OPC 工具箱连续读取数据 我怎样才能实现这个 我已经设计了图形用户界面 但我无法将数据读入图形用户界面 就这样做 type opctoolMA
  • 归一化互相关的基础知识

    我正在尝试使用范数校正2 归一化互相关 http en wikipedia org wiki Cross correlation Normalized cross correlation 来自 MATLAB 用于计算发育中胚胎中移动形状的速
  • 垂直子图的单一颜色条

    我想让下面的 MATLAB 图有一个沿着两个子图延伸的颜色条 像这样的事情 使用图形编辑器手动完成 Note 这与提出的问题不同here https stackoverflow com questions 39950229 matlab t
  • Python 或 C 语言中的 Matlab / Octave bwdist()

    有谁知道 Matlab Octave bwdist 函数的 Python 替代品 此函数返回给定矩阵的每个单元格到最近的非零单元格的欧几里得距离 我看到了一个 Octave C 实现 一个纯 Matlab 实现 我想知道是否有人必须用 AN
  • 如何在Matlab中绘制网络?

    我有一个矩阵AMatlab中的维数mx2每行包含两个节点的标签 显示网络中的直接链接 例如 如果网络有4矩阵的节点A可能A 1 2 1 3 2 1 2 4 3 2 4 1 4 2 其中第一行表示有一个链接来自1 to 2 第二行表示有一个链
  • 如何在向量中的所有点之间绘制线?

    我有一个包含二维空间中一些点的向量 我希望 MATLAB 用从每个点到每个其他点绘制的线来绘制这些点 基本上 我想要一个所有顶点都连接的图 你能用情节来做到这一点吗 如果可以 怎么做 一种解决方案是使用该函数为每个点组合创建一组索引MESH
  • Matlab 图像数据的 hist 函数

    我是 Matlab 新手 我想制作自己的函数 与 imhist 显示图像数据的直方图 完成相同的工作 但我对此完全是新手 我不知道如何做开发这样的功能 我开始做一些东西 但它非常不完整 function output args myhist
  • Matlab:条形图中缺少标签

    使用 Matlab 2012 和 2013 我发现设置XTickLabel on a bar图表最多只能使用 15 个柱 如果条形较多 则标签会丢失 如下所示 绘制 15 个条形图 N 15 x 1 N labels num2str x d
  • Numpy 相当于 MATLAB 的 hist [重复]

    这个问题在这里已经有答案了 由于某种原因 Numpy 的 hist 总是返回比 MATLAB 的 hist 少 1 个 bin 例如在 MATLAB 中 x 1 2 2 2 1 4 4 2 3 3 3 3 Rep Val hist x un
  • Matlab的导入函数的范围是什么?

    我正在尝试将一些用 Matlab 编写的代码转换为独立的 编译的 Matlab 应用程序 然而 在出现一些奇怪的错误之后 我意识到代码大量使用了从路径中添加和删除的操作 以避免多次使用多个具有相同名称 但结果 计算不同 的函数这一事实 环顾
  • matlab中无限while嵌套在for循环中

    我想做一个while循环 嵌套在for在 Matlab 中循环以查找数据中不同对之间的距离 我的数据具有以下形式 ID lon lat time 1 33 56 40 89 803 2 32 45 41 03 803 3 35 78 39
  • 获取向量幂的有效方法

    我编写了一个代码 在数值上使用勒让德多项式直至某个高 n 阶 例如 case 8 p 6435 x 8 12012 x 6 6930 x 4 1260 x 2 35 128 return case 9 如果向量x太长这会变得很慢 我发现说之
  • FMINCON 的替代方案

    除了 fmincon 之外还有其他更快 更高效的求解器吗 我正在使用 fmincon 来解决特定问题 但对于中等大小的向量变量来说 我的内存不足 我也没有任何超级计算机或云计算选项可供使用 我知道任何替代解决方案仍然会耗尽内存 但我只是想看

随机推荐