N圆最密堆积、最小外接正方形的matlab求解(二维、三维等圆Packing 问题)

2023-10-27

圆形最密堆积、最小外接正方形的matlab求解(二维、三维等圆Packing 问题)

惯例声明:本人没有相关的工程应用经验,只是纯粹对相关算法感兴趣才写此博客。所以如果有错误,欢迎在评论区指正,不胜感激。本文主要关注于算法的实现,对于实际应用等问题本人没有任何经验,所以也不再涉及。

0 前言

本文最开始的想法,是想到一个我有若干个球,究竟需要多大的箱子可以把这些球装下。

后来大概查了一下资料,发现这其实是一个最优化的问题,而且似乎还非常复杂。对于圆来说,还有比较简单的优化方法,但是对于复杂图形来说,则非常困难。

自己也不是专门搞最优化的,就不编自己的函数了,直接用matlab现成的函数进行求解。下面举两个例子作为说明。

更好的例子可参见这篇2019年的论文:
王正理《等圆Packing问题高效求解算法研究》
20以下的最密堆积可以直接在wiki百科上查表得到,词条为:Circle packing in a square
10000以下的最密堆积可以在这个网站查到:
http://hydra.nat.uni-magdeburg.de/packing/csq/csq.html

1 N个圆的最小外接正方形求解

这个先用2维平面问题作为引入。

优化函数用的是fmincon()函数。
这里之前也试过PSO算法,但是估计维度太多,有些空穴小球移动完全不影响最终外接矩形,所以收敛速度异常的慢。经常出现某一些圆挤到一块,但某些圆离得很远。所以还是用传统的最优化方法。

目标优化函数,也就是让其最小的函数,就是正方形的变长。
边界大致设置了左右边界,防止圆离开边界太远。
非线性约束,就是计算每个圆之间的距离,防止发生重叠。

在计算过程中,最容易出现的现象就是圆和圆之间距离过大,就提前结束计算了,比如下面这个图:
请添加图片描述
为了让其收敛,需要手动的将各个圆之间的距离缩小。我这里用的方法比较简单,就是将所有坐标除以1.5或者其它大于1的数,让其整体向左下角压缩。通常在计算一定步骤之后,再进行压缩,然后继续计算,反复多次,可以让其收敛到较好的结果。

最终代码如下:

clear
clc
close all
%计算圆的最小外接矩形(任意数量N)
%利用fmincon算法
%求解函数最小值

N=13;%圆的数量

%设置optimoptions的输入
fun = @MinValue;
lb = -2*ones(1,N*2);%[xi,yi,xi,yi,...]
ub = (4*N-2)*ones(1,N*2);

A = [];
b = [];
Aeq = [];
beq = [];

%按照网格布置初始圆
NMesh=ceil(sqrt(N));
[XMesh,YMesh]=meshgrid(0:4:(4*NMesh-1),0:4:(4*NMesh-1));
XYMesh=[XMesh(:),YMesh(:)]';
x0=XYMesh(1:2*N);
x0=x0+rand(1,2*N)-0.5;%添加随机性

%非线性约束,目的是让圆和圆之间不重叠
nonlcon = @NolinearCondition;%设定非线性约束条件

options = optimoptions('fmincon','Display','iter','Algorithm','interior-point','MaxFunctionEvaluations',inf);
x = fmincon(fun,x0,A,b,Aeq,beq,lb,ub,nonlcon,options);
%放大圆形,然后再计算一次。相当于让圆膨胀一下,然后利用约束条件再迭代一下
x=x/1.2;
options = optimoptions('fmincon','Display','iter','Algorithm','sqp','MaxFunctionEvaluations',inf,'MaxIterations',1e5);
x = fmincon(fun,x,A,b,Aeq,beq,lb,ub,nonlcon,options);
%放大圆形,然后再计算一次。相当于让圆膨胀一下,然后利用约束条件再迭代一下
x=x/1.05;
x = fmincon(fun,x,A,b,Aeq,beq,lb,ub,nonlcon,options);

%绘图
figure()
hold on
for k=1:N
    rectangle('Position',[x(2*k-1)-1,x(2*k)-1,2,2],'Curvature',1)
end
minX=min(x(1:2:end-1));
maxX=max(x(1:2:end-1));
minY=min(x(2:2:end));
maxY=max(x(2:2:end));
rectangle('Position',[minX-1,minY-1,maxX-minX+2,maxY-minY+2],'Curvature',0)


%非线性约束
function [c,ceq] = NolinearCondition(x)
%格式固定,c(x) ≤ 0 和 ceq(x) = 0。如果没有就是[]
N=length(x)/2;%点的数量
%转化坐标
xy=zeros(2,N);
xy(:)=x(:);
xy=xy';
%计算距离
DAll=pdist(xy,'squaredeuclidean');%距离的平方(这样省去了根号,加快计算速度)
%N个小球之间不碰撞,计算所有的负距离之和
DAll=DAll-4;
DNeg=sum(DAll(DAll<0));

%要让c<=0
c = -DNeg;%
ceq = [];
end

%评价函数
function V=MinValue(x)
%求包围两个圆的最小正方形边长

%x=[x1,y1,x2,y2,....]
%N=length(x)/2;%点的数量

%半径为1的圆
minX=min(x(1:2:end-1))-1;
maxX=max(x(1:2:end-1))+1;
minY=min(x(2:2:end))-1;
maxY=max(x(2:2:end))+1;
%计算正方形边长
L=max([maxX-minX,maxY-minY]);

V=L;
end

下面举几个最终结果,注意,这里只是给出了较优的解。因为小球数量越多,维度越大,几乎没有人能够说自己给出的解就是最优解。

N=9时的计算结果,显而易见,最密堆积就是3×3的形式。小球半径为1,正方形变长为6。
请添加图片描述
N=13的情况:
请添加图片描述
N=47的情况:

请添加图片描述
N=100的情况,出乎意料最密堆积不是10×10的方形堆积结构,而是更倾向于六边形的六方堆积结构,这里给出的最小正方形边长为19.7。这个解并不是最优解,因为这个正方形里面感觉还有不少空隙可以填充。
目前的最优解是05年得到的,最终正方形边长为19.45,参考来源我前言给的那个网站。
请添加图片描述

2 N个球的最小外接立方体求解

这里其实就是把上面代码中的2D换为3D,然后把各个函数也对应更改了一下,具体计算方法没有太多变化。

代码如下:

clear
clc
close all
%计算球的最小外接正方体3D
%利用fmincon算法
%求解函数最小值

N=9;
fun = @MinValue;
lb = -2*ones(1,N*3);%[xi,yi,zi,xi,yi,zi,...]
ub = (4*N^(1/3)-2)*ones(1,N*3);
%小球半径为1
A = [];
b = [];
Aeq = [];
beq = [];

%按照网格布置初始圆
NMesh=ceil(N^(1/3));
[XMesh,YMesh,ZMesh]=meshgrid(0:4:(4*NMesh-1),0:4:(4*NMesh-1),0:4:(4*NMesh-1));
XYMesh=[XMesh(:),YMesh(:),ZMesh(:)]';
x0=XYMesh(1:3*N);
x0=x0+rand(1,3*N)-0.5;%添加随机性

nonlcon = @NolinearCondition;%设定非线性约束条件

options = optimoptions('fmincon','Display','iter','Algorithm','interior-point','MaxFunctionEvaluations',inf);
x = fmincon(fun,x0,A,b,Aeq,beq,lb,ub,nonlcon,options);
%放大圆形,然后再计算一次。相当于让圆膨胀一下,然后利用约束条件再迭代一下
x=x/1.2;
options = optimoptions('fmincon','Display','iter','Algorithm','sqp','MaxFunctionEvaluations',inf,'MaxIterations',1e5);
x = fmincon(fun,x,A,b,Aeq,beq,lb,ub,nonlcon,options);
%放大圆形,然后再计算一次。相当于让圆膨胀一下,然后利用约束条件再迭代一下
x=x/1.05;
x = fmincon(fun,x,A,b,Aeq,beq,lb,ub,nonlcon,options);


figure()
camlight('headlight')
hold on
for k=1:N
    [X,Y,Z] = ellipsoid(x(k*3-2),x(k*3-1),x(k*3),1,1,1,100);
    h=surf(X,Y,Z,'EdgeColor','none','FaceColor',gallery('uniformdata',[1,3],k),...
        'FaceAlpha',0.8);
    h.DiffuseStrength=0.8;
    h.SpecularStrength=0.2;
end
view(3)
axis equal



%非线性约束
function [c,ceq] = NolinearCondition(x)
%格式固定,c(x) ≤ 0 和 ceq(x) = 0。如果没有就是[]
N=length(x)/3;%点的数量
%转化坐标
xyz=zeros(3,N);
xyz(:)=x(:);
xyz=xyz';
%计算距离
DAll=pdist(xyz,'squaredeuclidean');%距离的平方(这样省去了根号,加快计算速度)
%N个小球之间不碰撞,计算所有的负距离之和
DAll=DAll-1*4;
DNeg=sum(DAll(DAll<0));

%要让c<=0
c = -DNeg;%
ceq = [];
end

%评价函数
function V=MinValue(x)
%求包围很多球体的最小立方体

%x=[x1,y1,x2,y2,....]
%N=length(x)/2;%点的数量

%半径为1的圆
minX=min(x(1:3:end-2))-1;
maxX=max(x(1:3:end-2))+1;
minY=min(x(2:3:end-1))-1;
maxY=max(x(2:3:end-1))+1;
minZ=min(x(3:3:end-0))-1;
maxZ=max(x(3:3:end-0))+1;

%计算立方体边长
L=max([maxX-minX,maxY-minY,maxZ-minZ]);


V=L;
end

然后看一下输出结果:

当N=9时显然是体心立方堆积:
请添加图片描述
当N=27时,最密堆积为3×3×3的结构:
请添加图片描述
下面随便选取一个N=43的结果:
请添加图片描述

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

N圆最密堆积、最小外接正方形的matlab求解(二维、三维等圆Packing 问题) 的相关文章

  • 作为动画的八度情节点

    我有以下八度脚本 TOTAL POINTS 100 figure 1 for i 1 TOTAL POINTS randX rand 1 randY rand 1 scatter randX randY hold on endfor 当我运
  • 如何为已编译的 MATLAB 创建安装程序并要求用户接受我们的许可条款?

    我正在 MATLAB 中编写程序分发给 Windows 用户 我使用 MATLAB 编译器和 MATLAB r2014a 版本来创建程序 我可以使用 MATLAB 应用程序编译器创建 Windows 安装程序 并且它的工作效果可以接受 但是
  • getappdata 在 MATLAB 中返回空矩阵

    我有一段代码 我在其中使用setappdata然后我使用以下方式调用数据getappdata即使它不为空 它也会返回一个空矩阵 我的一段简化代码如下 function edit1 Callback hObject eventdata han
  • Python 或 C 语言中的 Matlab / Octave bwdist()

    有谁知道 Matlab Octave bwdist 函数的 Python 替代品 此函数返回给定矩阵的每个单元格到最近的非零单元格的欧几里得距离 我看到了一个 Octave C 实现 一个纯 Matlab 实现 我想知道是否有人必须用 AN
  • Matlab 一个图上有多个图例 2014b

    我想在一个地块上有多个传说 该解决方案在 2014b 版本之前完美运行 我试图弄清楚如何使用手柄优雅地制作它 但到目前为止还没有成功 欢迎任何想法 2013b 的示例 x 1 50 y1 sin x 2 y2 cos x 2 f figur
  • 从 MATLAB 调用 Java?

    我想要Matlab程序调用java文件 最好有一个例子 需要考虑三种情况 Java 内置库 也就是说 任何描述的here http docs oracle com javase 6 docs api 这些项目可以直接调用 例如 map ja
  • 在 MATLAB 中模拟 C++ 模板

    我试图找出创建 C 模板或 Java 通用对象的替代方案的最佳方法 出于多种不同的原因 我过去曾多次想这样做 但现在我想做的是为几个相关的类创建 saveobj 和 loadobj 函数 我的想法是 我想要一组通用的例程来创建默认结构 然后
  • 如何正确从表中删除 NaN 值

    在 Matlab 中阅读 Excel 电子表格后 不幸的是 我的结果表中包含了 NaN 例如这个 Excel 表格 将产生此表 其中出现额外的 NaN 列 我尝试使用以下代码片段删除 NaN measurementCells readtab
  • Matlab:条形图中缺少标签

    使用 Matlab 2012 和 2013 我发现设置XTickLabel on a bar图表最多只能使用 15 个柱 如果条形较多 则标签会丢失 如下所示 绘制 15 个条形图 N 15 x 1 N labels num2str x d
  • 以 2 为底的矩阵对数

    Logm 取矩阵对数 并且log2 取矩阵每个元素以 2 为底的对数 我正在尝试计算冯 诺依曼熵 它涉及以 2 为底的矩阵对数 我该怎么做呢 如果将 以 2 为底 的矩阵指数定义为B expm log 2 A 或者如果您类似地通过特征分解直
  • 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 oncleanup 函数?

    我有一个编译好的 matlab 程序 可以自动调整机器参数 在调整周期结束时 我需要恢复一些原始设置 有时会发生意外错误 有时用户会发现调整算法未正常工作 因此应终止 使用 control C 如果发生可预测的错误 我可以使用 try ca
  • 将 kinect RGB 和深度值转换为 XYZ 坐标

    我正在寻找一种简单的方法将 kinect RGB 和深度值转换为 XYZ 坐标 使用 MATLAB 我的目标是一个输入为以下内容的函数 每个点的 RGB 和深度值Kinect相机 并输出 每个点的 x y 和 z 值 RGB 深度 RGB
  • 通过多次合并相同的行向量来构建矩阵

    有没有一个matlab函数可以让我执行以下操作 x 1 2 2 3 然后基于x我想建立矩阵m 1 2 2 3 1 2 2 3 1 2 2 3 1 2 2 3 您正在寻找REPMAT http www mathworks com help t
  • 在 MATLAB 中绘图后恢复轴

    从文本文件绘制多种方法的输出后 未显示轴的右侧和上侧 我需要拥有它们并将它们加粗 就像当前的轴一样 绘制的数据来自存储每种方法数据的文件 每个数据文件都是一个 256x2 文件 包含 0 1 之间的值 第一列是精度 第二列是召回率 figu
  • 如何在 MATLAB 中将矩阵元素除以列总和?

    有没有一种简单的方法可以将每个矩阵元素除以列和 例如 input 1 4 4 10 output 1 5 4 14 4 5 10 14 以下是执行此操作的不同方法的列表 使用bsxfun https www mathworks com he
  • matlab 中的动画绘图

    我正在尝试创建一个三角形的动画图 最终结果应该是十个三角形 后面跟着两个更大的三角形 后面跟着一条直线 使用matlab文档 https de mathworks com help matlab ref drawnow html 我最终得到
  • 更新:随机将行添加到矩阵中,但遵循严格的规则

    以下是一个更大的矩阵的一部分 0 1 0000 1 0000 77 0000 100 0000 0 0 2500 0 1 0000 1 0000 72 0000 100 0000 0 2500 0 2500 0 1 0000 1 0000
  • MATLAB 变量传递和惰性赋值

    我知道在 Matlab 中 当将新变量分配给现有变量时 会进行 惰性 评估 例如 array1 ones 1 1e8 array2 array1 的价值array1不会被复制到array2除非元素array2被修改 由此我推测Matlab中
  • 如何从 matlab 调用 Qtproject?

    我在 matlab 中有一个函数可以写入一个 file txt 我在 qt 项目中使用它 So 当我使用 unix 获取要运行的 qt 编译可执行文件时 我有一个 Matlab 文件 但出现错误 代码 unix home matt Desk

随机推荐

  • 不容错过的Vue2.0组件开发

    简述 http www jianshu com p 313f11bccb33 utm source tuicool utm medium referral 本文针对于有Vue有一定基础的人学习了解 环境搭建等入门教程网上很多 大家自行学习
  • [ 注意力机制 ] 经典网络模型1——SENet 详解与复现

    Author Horizon Max 编程技巧篇 各种操作小结 机器视觉篇 会变魔术 OpenCV 深度学习篇 简单入门 PyTorch 神经网络篇 经典网络模型 算法篇 再忙也别忘了 LeetCode 注意力机制 经典网络模型1 SENe
  • 增程式电动汽车电控系统优化方法【matlab】

    一 主要内容 针对增程式电动汽车的传动系统架构 结合增程式乘用车和增程式电动公交的设计 对传动系统关键部件选型匹配以及电控系统工作模式进行论述 并论述了工况对行驶里程 以及电池充放电的影响因素 对通用汽车的Volt增程式电动汽车进行分析研究
  • B站价值60亿跨年晚会背后的微服务治理

    B站价值60亿跨年晚会背后的微服务治理 大家都知道微服务有两个痛点 一个是如何拆分微服务 微服务的边界怎么划分制定 二是微服务上了规模之后如何管理 因为只要上了规模 任何小小的问题都可能会被放大 最后导致雪崩效应 一 微服务化带来的挑战 上
  • 《Spring 5.x源码解析之Spring AOP 注解驱动使用及其实现原理》

    Spring 5 x源码解析之Spring AOP 注解驱动使用及其实现原理 学好路更宽 钱多少加班 mercyblitz 一 前言 大家好 欢迎阅读 Spring 5 x源码解析 系列 本篇作为该系列的第二篇 重点介绍Spring AOP
  • 离线搭建深度学习环境

    离线搭建深度学习环境 文章目录 离线搭建深度学习环境 Anaconda3离线安装 借助可联网PC下载安装包 安装Anaconda3 配置深度学习环境 获取深度学习环境 打包深度学习环境 拷贝深度学习环境 添加深度学习环境到环境列表 有时出于
  • Linux使用套接字 udp协议传输

    第一步是来认识库 需要哪些库 需要哪些库中的函数 哥们也只是 初学者 仅仅只是会调用的地步 后面有机会再加深 首先咱们需要清除的知道工作流程 第二步是直接写代码 开发工具 qtcreator6 环境 win10 虚拟机 ubuntu20 0
  • Vue学习杂记(五)——loader的使用

    Vue学习杂记 五 loader的使用 一 什么是loader 二 loader处理css 三 loader处理图片 四 loader处理高级的js语法 参考文献 引言 loader其实也是webpack系列的内容 考虑到webpack涉及
  • gradle使用教程,小白一篇就够

    概述 Gradle是新一代构建工具 从0 x版本一路走来虽然国内可寻的资料多了一些 但都是比较碎片化的知识 官方的Userguide虽然是业内良心之作 但无奈太长 且版本变化较快 又鉴于很多同学一看到英文内心便已认定无法读懂 遂打算利用业余
  • E tensorflow/stream_executor/cuda/cuda_dnn.cc:352] Loaded runtime CuDNN library: 5005 (compatibility

    WARNING tensorflow From usr local lib python2 7 dist packages tensorflow python util tf should use py 170 initialize all
  • MySQL逻辑架构图分析

    MySQL逻辑架构图 大体来说 MySQL 可以分为 Server 层和存储引擎层两部分 Server层 大多数MySQL的核心服务功能都在这一层 包括连接器 查询缓存 分析器 优化器 执行器 以及所有内置函数 日期 时间 数学 加密函数等
  • pnpm:高效、快速的npm

    什么是pnpm performent npm 速度快 节省磁盘空间的软件包管理器 为什么使用pnpm 使用npm安装依赖时 每次都会下载文件到硬盘中 当项目数量较多时 依赖包会占据大量的内存 pnpm就是解决这个问题的 pnpm如何解决 p
  • 手把手教你设置Typora的图床-gitee

    所需环境 typora node软件 所需软件及配置文末可下载 typora的激活安装可看以往教程点我查看typora激活 typora结合gitee图床的优势 分享文件只需要分享一个 md文件即可 插入的图片依旧可以访问 图床不限制 访问
  • Python创建索引,批量插入数据测试

    测试 coding utf 8 Created on 2019 6 13 10 19 25 author chenlin3 import esSdk class EsSdkTest def test self name EsSdkTest
  • CVE-2023-21839 【vulhub weblogic 漏洞复现】

    漏洞概述 由于Weblogic IIOP T3协议存在缺陷 当IIOP T3协议开启时 允许未经身份验证的攻击者通过IIOP T3协议网络访问攻击存在安全风险的WebLogic Server 漏洞利用成功WebLogic Server可能被
  • Docker部署springboot项目并连接上docker的mysql

    首先 我是参考着几篇博客 https blog csdn net hangao233 article details 104395693 https www jianshu com p 397929dbc27d 第一步 先在虚拟机或服务器上
  • 【毕业设计】机器学习的员工离职模型研究-python

    目录 前言 课题背景和意义 实现技术思路 变量分析 数据导入 构建机器学习模型 1 1 复制数据删除不需要的变量 1 2 列变量属性分类 实现效果图样例 前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实习为毕业后面临的就业升学做准备
  • 谁动了我的奶酪:奶酪墙上的话 ----- 整理完整篇

    谁动了我的奶酪墙上的话 如果你无所谓 你会怎样做呢 每天的生活都会因偶然或必然的事而不断变化着 提醒自己要不断地适应变化 拥有奶酪 就拥有幸福 奶酪对你越重要 你就越想抓住它 如果你不改变 你就会被淘汰 如果你无所畏惧 你会怎样做呢 经常闻
  • 类和对象

    1 面向过程 在开发一个程序的时候 看中的是中间的过程 每一个过程步骤都需要自己去做 例如C语言 看中的是过程的开发 2 面向对象 当开发一个程序的时候 不看重具体的过程 看中谁能帮我去完成这件事情 找人 对象 帮我去做 前期去设计类的时候
  • N圆最密堆积、最小外接正方形的matlab求解(二维、三维等圆Packing 问题)

    圆形最密堆积 最小外接正方形的matlab求解 二维 三维等圆Packing 问题 0 前言 1 N个圆的最小外接正方形求解 2 N个球的最小外接立方体求解 惯例声明 本人没有相关的工程应用经验 只是纯粹对相关算法感兴趣才写此博客 所以如果