У меня есть код для подсчета перестановок и комбинаций, и я стараюсь, чтобы он работал лучше для больших чисел.
Я нашел лучший алгоритм для перестановок, который позволяет избежать больших промежуточных результатов, но я все же думаю, что я могу сделать лучше для комбинаций.
До сих пор я включил специальный случай, чтобы отразить симметрию nCr, но мне все же хотелось бы найти лучший алгоритм, который позволяет избежать вызова факториала (r), что является излишне большим промежуточным результатом. Без этой оптимизации последний доктрист слишком долго пытается вычислить факторный (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)