圆排列问题

1.问题
给定n个大小不等的圆c1,c2,…,cn,现要将这n个圆排进一个矩形框中,且要求各圆与矩形框的底边相切。圆排列问题要求从n个圆的所有排列中找出有最小长度的圆排列。例如,当n=3,且所给的3个圆的半径分别为1,1,2时,这3个圆的最小长度的圆排列如图所示。其最小长度为2+4*sqrt(2)

2.解析
圆排列的解空间是一棵排列树,采用优先队列式分支限界法找出最小圆排列长度。

首先,用一个最小堆来表示活节点优先队列,其优先值定义为剩下未排列圆的所有半径和,或者定义为剩下未排列圆的相切距离和。

其次,要解决镜像对称问题。例如有3个圆,半径分别为1,2, 3。其排列1,2,3与3,2,1互为镜像排列,具有相同的圆排列长度,因此,只有计算-一个就够。这样一来,可以减少一半的计算量。

解决方法:假设有n个圆排列: 1,2,…,. n。只要算出n!/2种排列,具体排列如下:
1,…,2; 2,…,3;
1,…,3; 2,…,4;
… … …
1,…,n; 2,…,n; n-1,…,n;

因此只要确定第-一个和最后-一个位置的数就可以,在排列时,可以从第二个位置到第n-1个位置之间排列。

如果所给的n个圆中有k个圆有相同的半径,则这k个圆产生的k!个完全相同的圆排列,只计算一个就够,因此,相同半径的圆越多,剪去的节点就越多。

解决相同半径圆排列方法如下:如下图有3个相同半径的圆,当第一个圆与第二个圆要交换位置时,先判断它们的半径是否相同,若是,则剪枝,否则,可以交换。

为了加快搜索节点,可以进一步加强下界约束条件。假设,有n个圆,其中前面m个圆已经确定完位置,还有n-m个没确定位置。那么,当搜索到第m+1个圆时,min_len(m)+2.0*sqrt(r[m]r[m+ 1])+len_r(n-1-m)<min,加上len_r(n-1-m) 后,
min_len(m)+2.0
sqrt(r[m]*r[m+1])+len_r(n-1-m)<min总是成立。
因为len_r(n-1-m)=r[m+2]+r[m+3]…+r[n]总比确定完位置后的圆排列的长度更小。

3.设计
double low=0.0;
double high=0.0;
for( j=1;j<=n;j++)
{
if(E.x[j]-E.r[j]<low)
low=E.x[j]-E.r[j]; //计算最左边
if(E.x[j]+E.r[j]>high)
high=E.x[j]+E.r[j];//计算最右边}
if((high-low)<min) min=high-low; //更新min

4.分析
因为根据不同的排列方法取最小长度的圆排列,所以根据全排列公式要进行n!次查找,每次完成一个结果集后,还要找到起点值与终点值。
所以时间复杂度是O(n!)

5.源码
https://github.com/ylx1234/RoundArrangement-

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值