回溯法:《圆排列问题》-python实现

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


 

#coding:utf-8
import sys
import math
import copy
cc = []


def bianchang(a, l, c):
    if l == 0:
        return 2 * a
    else:
        b = (a + c) ** 2 - (abs(a - c)) ** 2
        return l - c + math.sqrt(b) + a


def compute(d, a, n, l, c):                      #d表示输入半径的列表,a表示第几个半径,n表示半径的总共个数,l表示上一次计算的边长,c表示上一次圆的半径
    d1 = copy.deepcopy(d)                        #对d进行深拷贝
    if a == n:                                   #当计算到第n个半径时,将结果保存在列表cc中
        global cc
        cc.append(l)
        #print cc
    else:
        for i in range(0, len(d1)):
            if d1[i] != 0:
                t = bianchang(d1[i], l, c)      #当加入新的圆时,计算加入后的边长
                w = d1[i]
                d1[i] = 0                       #该半径计算完成后,将其置为0,标志已经计算结束
                compute(d1, a + 1, n, t, w)
                d1[i] = w                       #再将该半径的值恢复,方便下一次的回溯计算


if __name__ == '__main__':
    n = input()                                          #n表示输入半径的个数
    d = sys.stdin.readline().strip().split(' ')          #d表示输入的半径,以空格进行分割
    d = map(int, d)

    compute(d, 0, n, 0, 0)                               #回溯算法

    print min(cc)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT远征军

谢谢各位鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值