我有一些代码来计算排列和组合,并且我正在努力让它更好地适用于大量数字。
我找到了一种更好的排列算法,可以避免大的中间结果,但我仍然认为我可以在组合方面做得更好。
到目前为止,我已经放入了一个特殊情况来反映 nCr 的对称性,但我仍然想找到一个更好的算法来避免调用 factorial(r),这是一个不必要的大中间结果。如果没有这种优化,最后一个 doctest 会花费很长时间来计算阶乘(99000)。
任何人都可以提出一种更有效的计算组合的方法吗?
from math import factorial
def product(iterable):
prod = 1
for n in iterable:
prod *= n
return prod
def npr(n, r):
"""
Calculate the number of ordered permutations of r items taken from a
population of size n.
>>> npr(3, 2)
6
>>> npr(100, 20)
1303995018204712451095685346159820800000
"""
assert 0 <= r <= n
return product(range(n - r + 1, n + 1))
def ncr(n, r):
"""
Calculate the number of unordered combinations of r items taken from a
population of size n.
>>> ncr(3, 2)
3
>>> ncr(100, 20)
535983370403809682970
>>> ncr(100000, 1000) == ncr(100000, 99000)
True
"""
assert 0 <= r <= n
if r > n // 2:
r = n - r
return npr(n, r) // factorial(r)