问题

圆排列问题:给定n个圆的半径序列,将它们放到矩形框中,各圆与矩形底边相切,求具有最小排列长度的圆排列。

解析

圆排列问题的解空间是一棵排列树。按照回溯法搜索排列树的算法框架,设开始时a=[r1,r2,……rn]是所给的n个圆的半径,则相应的排列树由a[1:n]的所有排列构成。
1、compute函数可以想象其中任意的一个圆无限大或无限小,无限大的话那其余的圆就可以统统忽略了。因为已知所有圆的x坐标和半径r,很容易求出每个圆的左右坐标,通过比较找出最小的左部坐标和最大的右部坐标,一减就是该圆排列的长度,然后把每次不同的排列长度相比较,找到更小的minlen就更新。

2、 center函数计算圆在当前圆排列中的横坐标,由x^2 = sqrt((r1+r2)2-(r1-r2)2)推导出x = 2sqrt(r1r2)。注意排在任意位置的圆与其前或后的任意一个圆都有可能相切的,如图所示。

3、back函数,这里用到的核心方法就是回溯法,回溯最重要的就是求出界限函数.按问题性质,可画出子集树或排列树。if(cx+r[t]+r[1]<minlen)的作用是剪枝,先判断当前层是否在范围内,是则继续搜索下一层,否则直接回溯。下图是不进行剪枝时,六种可能性都搜索一遍的过程。

设计

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
double minlen, x[1010], r[1010];
int n;
double best[1010];
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++) {best[i] = r[i];}}
}double center(int t) {double tem = 0;for (int i = 1; i < t; i++) {tem = max(x[i] + 2.0 * sqrt(r[i] * r[t]),tem);}return tem;
}void back(int t) {if (t > n)  compute();else {for (int i = t; i <= n; i++) {swap(r[t], r[i]);double cx = center(t);if (cx + r[1] + r[t] < minlen) {x[t] = cx;back(t + 1);}swap(r[t], r[i]);}}
}int main() {scanf("%d", &n);for (int i = 1; i <= n; i++)    scanf("%lf", &r[i]);minlen = inf;back(1);printf("最小排列长度:%f\n", minlen);for (int i = 1; i <= n; i++) {printf("%f", best[i]);if (i != n)    printf("\n");}
}

分析

代码的核心复杂度在back函数递归过程中,最坏情况下啊复杂度为O(n!),而每次递归的复杂度为O(n),所以总结得出复杂度为:

源码

github源码地址

算法大作业 圆排列问题相关推荐

  1. 算法-大作业-圆排列问题

    1.问题 给定n个圆的半径序列,将它们放到矩形框中,各圆与矩形底边相切,求具有最小排列长度的圆排列. 2.解析 圆的摆放位置不同,得到的结果可能不同,所以这是一个排列问题,在回溯里面需要添加全排列的代 ...

  2. 算法分析大作业 圆排列问题

    算法分析与设计 圆排列问题 问题描述: 给定n个圆的半径序列,将它们放到矩形框中,各圆与矩形底边相切,求具有最小排列长度的圆排列. 算法 假设三个圆的半径分别为1,1,2.那么这种情况的圆排列长度为2 ...

  3. 算法大作业之津巴布韦问题的C语言实现

    文章目录 题目描述 样例 项目总体设计 方案一:基于DFS的递归算法 1.1 数字类型的实现方法: 1.2. 字符串类型的实现方法: 方案二:基于交换的递归算法(减治思想) 方案三:基于字典序的非递归 ...

  4. 哈工大2020秋算法设计与分析大作业(一)

    哈工大2020秋算法设计与分析大作业(一) 前言 正文 1 论文题目 标题 作者 刊物 2 论文阅读报告 2.1 摘要 2.2 问题定义 2.3 算法或证明过程 2.4 实验结论 哈工大2020秋算法 ...

  5. 华南理工大学计算机操作系统课程设计大作业银行家死锁避免算法模拟,2016春操作系统大作业银行家死锁避免算法模拟.doc...

    文档介绍: 2016春操作系统大作业银行家死锁避免算法模拟20160501华南理工大学"计算机操作系统"课程设计大作业计算机科学与技术专业:春2015班级:号:2015047420 ...

  6. python range从大到小排列_python 十大经典排序算法

    人生苦短,我用python! 排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存.常见的内部排序 ...

  7. Java实验——设计一个数组模型,用于存储体育项目成绩男生体育项目有足球、长跑和铅球,女生体育项目有跳舞、体操、游泳。设计排序算法,将变量a、b、c中的数值按大小顺利进行互换(从大到小排列)。

    设计一个数组模型,用于存储体育项目成绩:男生体育项目有足球.长跑和铅球,女生体育项目有跳舞.体操.游泳. import java.util.Scanner;public class DataArray ...

  8. 数据结构大作业_聊聊我的数据结构与算法课

    在这样一个天天见证历史的特殊学期,地空数算2020结束了. 从秋季学期开始,计算概论B和数据结构与算法B都将纳入公共计算机基础课的轨道,全校理科生统一选课.统一大纲.统一时间.统一上机.统一考评. 虽 ...

  9. 算法设计与分析: 6-8 圆排列问题

    6-8 圆排列问题 问题描述 给定 n 个大小不等的圆 c1,c2,...,cn c 1 , c 2 , . . . , c n c_1 , c_2 , ... , c_n ,现要将这 n 个圆排进一 ...

最新文章

  1. python编写函数isodd(x)_python函数对象
  2. msm8953之串口dts配置
  3. 雷神开机logo更改_雷神911 pro-钛空版开售,陪你过一个不一样的520
  4. 【题解】JSOIWC2019 Round4
  5. 十个最适合 Web 和 APP 开发的 NodeJS 框架
  6. Github(1)-概览,初始化仓库
  7. Laravel核心解读--Database(四) 模型关联
  8. 用易拉罐做机器人教程_不会c4d就做不出3d设计?用ps照样可以,教程在这里
  9. 基于JAVA+SpringBoot+Mybatis+MYSQL的智慧水产养殖系统
  10. 2017 年,阿里巴巴开源的那些事儿
  11. java 集成ibm mq 教程_IBM MQ JMS 与spring的整合
  12. apply族函数应用指南
  13. 振南的 znFAT(前言)
  14. c语言-蓝桥杯-平面切割
  15. 汉字转拼音接口 get请求 无需注册
  16. elasticsearch 在不是 not_analyzed 的前提下如何全匹配的效果
  17. 变更 Rancher Server IP 或域名
  18. 工厂模式简介和应用场景
  19. JAVA数独解题(四):数对法
  20. Premiere Pro之字幕添加(三)

热门文章

  1. 华硕PRIME B660M-K D4 i5-13600KF黑苹果efi引导文件
  2. A001-书籍-像程序员一思考
  3. 【空间单细胞组学】第2期:乳腺癌患者经anti-PD1治疗后,肿瘤内变化的单细胞图谱
  4. PLC实验系列:十字路口交通灯的设计(运用比较指令)
  5. 男生报计算机专业前景,男生学什么专业就业前景好?
  6. 中班机器人教室设计方案_机器人创客教室方案
  7. Spark2 Failed to send RPC 5346982634 to /ns1:58312: java.nio.channels.ClosedChannelException
  8. 高维数据降维 国家自然科学基金项目 2009-2013 NSFC Dimensionality Reduction
  9. 专利挖掘文章研读笔记
  10. 列出100以内整数中7的倍数或是含7的数