卢卡斯定理及python实现

20 篇文章 0 订阅
4 篇文章 0 订阅

卢卡斯定理

最近接触到的一个大组合数求余方法,个人觉得推导过程比较晦涩难懂,但是在组合数比较大的时候性能的确是优秀,所以这里记录一下。卢卡斯定理的推导式如下(以如既往的铅笔加手写~剩下码公式的时间去板砖了我。。。):
在这里插入图片描述

python实现

这里给出一个递推的python实现方法

class cmnModP:
    def __init__(self,p):
        self.p=p
        self.fc=[1]
        for i in range(1,p+1):
            self.fc.append(i*self.fc[-1])
    def C(self,m,n):
        if m==n:return 1
        if m<n:return 0
        return self.fc[m]/self.fc[n]/self.fc[m-n]

    def lucas(self,m,n):
        if n==0:return 1
        return self.lucas(m//self.p,n//self.p)*self.C(m%self.p,n%self.p)%self.p

与传统方法的性能对比

在这里插入图片描述
我们用传统意义上的求余方法如上图所示,实现如下:

class oldMethod:
    def C(self,m,n):
        return  math.factorial(m)//math.factorial(n)//math.factorial(m-n)

性能对比

我们这里从10到1000000从中选出20%的数,然后对3取余,其求解耗时情况如下,可以发现在m,n都比较大时,卢卡斯定理求解该问题性能可以用优异来形容。

-------当m=10,n=2时二者的求解耗时情况对比------
卢卡斯求解结果: 0
传统方法求解结果 0
卢卡斯方法耗时情况: 0.0   传统方法求值的耗时情况: 0.0
-------当m=100,n=20时二者的求解耗时情况对比------
卢卡斯求解结果: 0
传统方法求解结果 0
卢卡斯方法耗时情况: 0.0   传统方法求值的耗时情况: 0.0
-------当m=1000,n=200时二者的求解耗时情况对比------
卢卡斯求解结果: 0
传统方法求解结果 0
卢卡斯方法耗时情况: 0.0   传统方法求值的耗时情况: 0.0
-------当m=10000,n=2000时二者的求解耗时情况对比------
卢卡斯求解结果: 0
传统方法求解结果 0
卢卡斯方法耗时情况: 0.0   传统方法求值的耗时情况: 0.01999807357788086
-------当m=100000,n=20000时二者的求解耗时情况对比------
卢卡斯求解结果: 0
传统方法求解结果 0
卢卡斯方法耗时情况: 0.0   传统方法求值的耗时情况: 1.229926347732544
-------当m=1000000,n=200000时二者的求解耗时情况对比------
卢卡斯求解结果: 0
传统方法求解结果 0
卢卡斯方法耗时情况: 0.0   传统方法求值的耗时情况: 135.11490297317505

推导过程

网上有很多推导过程,个人觉得从二项式的性质方面的求解更容易理解,这里就不赘述,该天有了更精巧的推导方式再来补充。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值