- 问题
给定n个圆的半径序列,将它们放到矩形框中,各圆与矩形底边相切,求具有最小排列长度的圆排列。 - 解析
该问题是一个排列问题,问题的解存储在序列r={r1,r2,r3…}中,问题的解空间树是一颗排列树。用x={x1,x2,x3…}表示当前排列的各个圆的圆心。
下界函数:用Center(t)计算新增圆的圆心,每次新增一个圆则排列的序列会增长,比较center(t)+r[t]+r[0]这个值(注意不是序列中总长,只是t号圆的最右端的长度)和已知序列长度min比较,如果大于min则剪枝。
用compute计算整个序列的长度,遍历每一个圆,记录左端low和右端high,迭代得到low的最小值和hight的最大值,最后做差即可得到序列长度。 - 设计
float center(int t)
{
float res=0;
for(int i=0;i<t;i++)
{//(rt+rj)2-(rt-rj)2=4rjrt
float temp=x[i]+2.0*sqrt(r[t]*r[i]);
if(temp>res) res=temp;
}
return res;
}
void compute()
{
float low=0,high=0;
for(int i=0;i<n;i++)
{
float tempLow=x[i]-r[i];
float rempHigh=x[i]+r[i];
if(tempLow<low) low=tempLow;
if(rempHigh>high) high=rempHigh;
}
if(high-low<minx) minx=high-low;
} - 分析
时间复杂度:对于排列树,共有n!次计算;另外在每次计算圆心的过程中有O(n)次计算时间,因此整体算法时间复杂度为T(n)=O((n+1)!) - 源码
https://github.com/CunHua-YYT/CunHua-YYT/blob/master/CircleSort.cpp
圆排列问题
最新推荐文章于 2021-12-14 11:48:13 发布