社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python版组合数计算方法优化思路和源码

Python小屋 • 8 年前 • 1034 次点击  

总体说明:本文的优化思路并不局限于Python,但C、C++、C#、Java等语言无法使用内置类型直接表示大整数,需要通过数组等特定形式并自己实现大整数乘除法才能实现,因此本文只介绍Python语言的实现。

按照标准的组合数公式,再结合Python标准库的阶乘函数factorial(),很容易写出下面的代码:

def cni(n, i):
    from math import factorial
    return factorial(n) // factorial(i) // factorial(n-i)


但是,在上面代码的执行过程中,很多计算是重复的,于是我在《Python可以这样学》和《Python程序设计开发宝典》中给出了下面的优化思路和代码,大幅度减少了重复的计算,提高了计算效率。主要思路是对组合数计算公式的分子分母进行展开,并约去重复计算。

def cni1(n,i):
    result=1
    Min,Max=sorted((i, n-i))
    for i in range(n,0,-1):
        if i> Max:
            result *=i
        elif i <= Min:
            result =result // i
    return result


非常感谢浙江温州永嘉县教师发展中心应根球老师又对这个算法进行了进一步优化,提供了下面的两段等价代码,通过自然数分布的对称性和一乘一除的结合,有效避免了中间结果过大而导致效率降低的问题。

def cni2(n,i):
    result = 1
    for j in range(0, i):
        result = result * (n-j) // (j+1)
    return result


def cni3(n,i):
    result = 1
    for j in range(1, i+1):
        result = result * (n-i+j) // j
    return result


下面是测试代码,大家可以修改参数进行更多测试,也欢迎提供更好的优化思路和代码。

n = 100000
i = 52019
print(cni1(n,i))
print(cni(n,i) == cni1(n,i)==cni2(n,i)==cni3(n,i))




----------喜大普奔----------

1、继《Python程序设计基础》《Python程序设计(第2版)》《Python可以这样学》系列图书之后,董付国老师新书《Python程序设计开发宝典》已于2017年8月1日在清华大学出版社出版。为庆祝新书《Python程序设计开发宝典》全面上架,清华大学出版社联合“赣江图书专营”淘宝店推出特价优惠活动,《Python程序设计开发宝典》原价69元,新书上架期间超低价39.8元,可以复制下面的链接使用浏览器打开查看图书详情和购买:

https://detail.tmall.com/item.htm?spm=a1z10.3-b-s.w4011-14464369246.84.46f16db0roWfX4&id=557107249812&rn=339cbc9df2bac424664103917dedfbd2&abbucket=8&tbpm=3

2、10月13日——15日,重庆,全国高校程序设计系列课程高级研究班,详见:全国高校程序设计系列课程高级研修班(Python)通知



今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/RIq9JVZzhn
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/3378