首页 > 编程语言 >随机化算法解决圆排列问题 - python解法

随机化算法解决圆排列问题 - python解法

时间:2022-10-31 16:36:38浏览次数:51  
标签:排列 min python 复杂度 len 随机化 算法 解法


问题描述

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

随机化算法解决圆排列问题 - python解法_python

算法设计

设计一个随机化算法,对于给定的n个圆,计算n个圆的最佳排列方案,使其长度尽可能小。

数据输入

由文件input.txt给出输入数据。第一行有1个正整数n (1≤n≤20)。接下来的1行有n个数,表示n个圆的半径。

随机化算法解决圆排列问题 - python解法_概率算法_02

解题思路

随机化算法

这里不展开介绍随机化算法,它在我看来只是一种使算法复杂度与输入数据解耦合的思想,并不是某种特定的算法。比如我们都知道快速排序对于不同的输入数据会有不同的时间复杂度,所以我们称其为不稳定的排序算法,而采用随机化的思想就能使其变成稳定的算法,最简单的办法就是对所有输入数据都进行一次随机排列。
在本问题中,解题思想也相同,所谓随机化只是将输入的圆半径给随机打乱罢了。

本题解题思路

本问题我没有采用递归、回溯等算法,想看该算法请移步(​​图文并茂详尽剖析圆排列问题​​)。

上面用回溯的算法,时间复杂度达到了O(n!),阶乘时间复杂度可是比指数还吓人,那还不如直接用几层循环了事呢。因此本文采用三层循环设计算法,时间复杂度里面两层肯定是O(n2),最外层时间复杂度不好统计,估摸着最坏也是O(n3)吧。关于性能我才用上文评论区中提供的数据进行测试(如下图),很快就出结果了(不到1秒),因此粗略估计本文算法效率高于上文。

随机化算法解决圆排列问题 - python解法_圆排列_03


基本思想很简单,定义三层循环,核心在circle_search函数中。第一层while循环控制是否该结束里面两层的循环,里面两层则每次分别交换两个圆的顺序。关于内层循环的j取值从0开始和从i+1开始应该都是没问题的,从0开始能减少最外层循环次数,从i+1开始则是因为反正最外层还有个循环能兜底。内两层循环思想参考冒泡即可。每次交换俩圆顺序,若比最小值更小则将最小值记为这次交换后的圆排列长度,如果交换后长度没有变小,那就得再换回来。至于最开始的将半径随机化,则只是将算法和输入数据解耦罢了。

至于求圆排列长度的方法,大家可以自己琢磨一下,也可以参考下上面提到那篇文章的方法:

随机化算法解决圆排列问题 - python解法_概率算法_04

完整代码如下(python3版本)

import numpy as np
import random

# 给定一个半径数组,计算其按顺序的长度
def get_len(a, n):
len = 0
if n < 1:
return None
if n == 1:
return a[0]
len += a[0]
for i in range(n - 1):
len += 2 * ((a[i]*a[i + 1]) ** (1/2))
len += a[-1]
return len


# 定义解圆排列问题的随机化算法
def circle_search(a, n):
global min_len
# 将输入数据中的圆的半径随机化,从而让算法性能与输入数据解耦合
a = random.sample(a, n)
# 计算随机化后的长度
min_len = get_len(a, n)
found = True
while(found):
found = False
for i in range(n):
for j in range(n):
a[i], a[j] = a[j], a[i]
if get_len(a, n) < min_len:
found = True
min_len = get_len(a, n)
else:
a[i], a[j] = a[j], a[i]

# 读取数据
with open('./input.txt', 'r') as f:
n = int(f.readline().strip())
a = [float(x) for x in f.readline().strip().split(' ')]
min_len = float('inf')
circle_search(a, n)
with open('output.txt', 'w') as f:
f.write(str(round(min_len, 5)))

随机化算法解决圆排列问题 - python解法_算法_05


标签:排列,min,python,复杂度,len,随机化,算法,解法
From: https://blog.51cto.com/u_15854687/5810308

相关文章

  • python中*的用法
    python中*是非常常见的一个运算符,它主要有以下几个功能:乘法运算符;函数形参表示可变参数;函数实参代表tuple;序列解包为tuple;zip解包运算;参考资料:​​Python3*和**运算符​......
  • python多继承及其super的用法
    python也具有多继承的功能,而同样的,大家能想到多继承必须要引入一些特定的方法来准确调用子类或基类的重载、重写的方法,否则会出现混乱。本文参考​​Multipleinheritance......
  • python中的round
    参考资料:​python的round函数使用​​python的round函数作用是四舍五入,其函数定义如下:round接收两个参数,第一个是数字,第二个是保留的位数,如果不显式给定第二位,则默认不保留......
  • 【python】list中extend和append的区别
    在python列表中,extend和append都可以往列表中加入元素,extend是扩充单个元素,如:a='abc123'b=[]b.extend(a)>>>b=['a','b','c','1','2','3']而append是扩......
  • 力扣409(java&python)-最长回文串(简单)
    题目:给定一个包含大写字母和小写字母的字符串 s ,返回 通过这些字母构造成的最长的回文串 。在构造过程中,请注意区分大小写。比如 "Aa" 不能当做一个回文字符串......
  • grpc demo python客户端 c++服务端
    项目需啊将网站上传的图片传入c++推理引擎,网站使用flask架构,python编写,图片推理引擎是一个单独的server,c++编写,因此用grpc来传输比较合适。理论上来说只要规定好proto文件,......
  • python爬虫基本概述
    python爬虫基本概述 一、爬虫是什么网络爬虫(Crawler)又称网络蜘蛛,或者网络机器人(Robots).它是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。换句话来说,它可......
  • linux安装python3.10
    1.下载python包https://www.python.org/ftp/python/3.10.5/Python-3.10.5.tgz2.安装依赖包yuminstall-ygccpatchlibffi-develpython-develzlib-develbzip2-dev......
  • python pip下载依赖到本地和本地安装
    pythonpip下载依赖到本地和本地安装环境:ubuntu18.0.4python3.6pip3list.txt文件内容(需要下载的安装包):certifi==2022.9.24 cffi==1.15.......
  • Python学习一:基本内容
    文章目录​​一、Python规范​​​​二、Python基本规范​​​​2.1注释​​​​1单行注释​​​​2多行注释​​​​2.2变量​​​​1定义变量名​​​​2输出变量名......