算法分析期末大作业-回溯算法-圆排列问题

1、问题

在这里插入图片描述

2、解析

第一个圆的圆心横坐标为0
定义x(k)数组算出排列第k个圆的圆心横坐标
minlen为最短的矩形的长度if(centerx+r[t]+r[1]<minlen)语句判断是否还要继续进行下去
bestr定义一个最优的圆的排序序列因为第K个圆不一定和第k-1个圆相切,如图:
在这里插入图片描述
所以要进行循环判断圆心横坐标选取最远的距离
可以得到排列树
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、设计

求圆心横坐标:
double center(int t) {//圆心坐标
double temp = 0;
//由于后面一个圆不一定与前一个圆相切,可能与前面的任一圆相切
for (int j = 1; j < t; j++) {
double xvalue = x[j] + 2.0 * sqrt(r[t]*r[j]);
if (xvalue > temp) {
//对于排列的第t个圆,距离最远的便是排列第t的圆的横坐标
temp = xvalue;
}
}
return temp;
//排列第一个的圆的圆心横坐标是0
}
回溯算法:
void backtrack(int t) {
if (t > n) {
compute();
}
else {
for (int j = t; j <= n; j++) {
swap(r[t], r[j]);
double centerx = center(t);//获取圆心横坐标
//如果某个圆加起来的序列长度比当前最小序列的长度还要小,则继续进行,否则结束
if (centerx + r[t] + r[1] < minlen) {
x[t] = centerx;
backtrack(t + 1);
}
swap(r[t],r[j]);
}
}
}
求矩阵的最短长度:
void compute() {
double low = 0, high = 0;//表示矩阵框的左右边界
for (int i = 1; i <= n; i++) {
if (x[i] - r[i] < low) {
low = x[i] - r[i];
}
if (x[i] + r[i] > high) {
high = x[i] + r[i];
}
}
if (high - low < minlen) {
minlen = high - low;
for (int i = 1; i <= n; i++) {
bestr[i] = r[i];
}
}
}

4、分析:

Backtrack函数需要O(n!)的时间复杂度,计算当前圆排列长度需要从头遍历到尾,需要O(n)计算时间,从而整个算法的时间复杂度为O((n+1)!)

5. 源码

源码地址:https://github.com/ACynj/circle.git

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值