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

圆形最密堆积、最小外接正方形的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',&#
  • 4
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值