简化二项式系数计算

时间:2014-12-14 14:13:24

标签: python algorithm math

我正在尝试减少以下二项式和的计算:

def binomial(m, k):
    result = 1
    for i in range(k):
        result = result * (m - i) / (i + 1)
    return result

n, t = 10, 20
bin2 = binomial(n + t, n)
for i in xrange(n + 1):
    bin2 = binomial(n + t - i, n)    # recalculation here. 
    # bin2 = bin2 * (t - i) / (n + t - i) my wrong implementation
    print bin2

我不喜欢的是在循环期间我应该使用先前计算的bin2重新计算bin2。我知道我必须使用here enter image description here

中的公式

但我的错误实现给出了错误的结果。任何想法我应该如何简化它?

3 个答案:

答案 0 :(得分:2)

您有一个错误的错误。更新前打印。

def binomial(m, k):
    result = 1
    for i in range(k):
        result = result * (m - i) / (i + 1)
    return result

n, t = 10, 20
bin2 = binomial(n + t, n)
for i in xrange(n + 1):
    print bin2
    bin2 = bin2 * (t - i) / (n + t - i)

答案 1 :(得分:0)

您可以在二项式函数中使用yield代替return,以使迭代器包含您的数字的所有二项式:

>>> def binomial(m, k):
...     result = 1
...     for i in range(k):
...         result = result * (m - i) / (i + 1)
...         yield result
... 
>>> list(binomial(6,3))
[6, 15, 20]

然后当您想根据for循环计算bin(30,10)bin(20,10)时,您可以将列表切片并反转:

>>> list(binomial(n,t))[-t:][::-1]

答案 2 :(得分:0)

您可以使用函数属性来保存以前的结果,并在函数的计算中使用它:

def foo(n):
    x = foo.previous + n
    foo.previous = x
    return x

foo.previous = 0

for n in xrange(5):
    print foo.previous, foo(n)

>>> 
0 0
0 1
1 3
3 6
6 10
>>> 

或使用装饰者:

import functools
def wraps(f):
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        try:
            p = f.previous
        except AttributeError as e:
            p = 0
        kwargs['previous'] = p
        result = f(*args, **kwargs)
        f.previous = result
        return result
    return wrapper

@wraps
def foo(n, previous = None):
    return n + previous

>>> 
>>> foo(2)
2
>>> foo(2)
4
>>> foo(2)
6
>>> foo(2)
8
>>>