Ho un codice per contare permutazioni e combinazioni e sto cercando di farlo funzionare meglio per grandi numeri.contando efficacemente combinazioni e permutazioni
Ho trovato un algoritmo migliore per permutazioni che evita grandi risultati intermedi, ma penso ancora che possa fare meglio per le combinazioni.
Finora, ho inserito un caso speciale per riflettere la simmetria di nCr, ma mi piacerebbe comunque trovare un algoritmo migliore che eviti la chiamata a factorial (r), che è un risultato intermedio inutilmente grande . Senza questa ottimizzazione, l'ultimo doctest impiega troppo tempo nel calcolare fattoriale (99000).
Qualcuno può suggerire un modo più efficiente per contare le combinazioni?
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)
Per un singolo nCr questo è meglio, ma quando si dispone di più nCr di (nell'ordine di N) allora l'approccio di programmazione dinamica è meglio, anche se ha un tempo di messa a punto lungo, dal momento che non sarà troppo pieno in un "bignum" se non necessario. – JPvdMerwe