web-dev-qa-db-fra.com

Calculer la valeur de n choisissez k

Quelle est la méthode la plus efficace pour évaluer la valeur de n choisit k? Je pense que la méthode de force brute serait de trouver n factoriel/k factoriel/(n-k) factoriel 

Une meilleure stratégie peut être d’utiliser dp selon cette formule formule récursive . Existe-t-il une autre méthode plus efficace pour évaluer n choisissez k? 

31
Nikunj Banka

Vous pouvez utiliser la formule multiplicative pour ceci:

enter image description here

http://en.wikipedia.org/wiki/Binomial_coefficient#Multiplicative_formula

27
Pedrom

Voici ma version, qui fonctionne uniquement en nombres entiers (la division par k produit toujours un quotient entier) et est rapide en O (k):

function choose(n, k)
    if k == 0 return 1
    return (n * choose(n - 1, k - 1)) / k

Je l'ai écrit récursivement parce que c'est si simple et si joli, mais vous pouvez le transformer en une solution itérative si vous le souhaitez.

40
user448810

La méthode la plus simple pour calculer les coefficients binomiaux (n choose k) sans déborder est d’utiliser le triangle de Pascal. Aucune fraction ni multiplication n'est nécessaire. (n choose k). La rangée nth et l'entrée kth du triangle de Pascal donnent la valeur.

Jetez un oeil à cette page . Il s'agit d'une opération O(n^2) avec seulement addition que vous pouvez résoudre avec une programmation dynamique. Cela va être ultra-rapide pour n'importe quel nombre pouvant tenir dans un entier 64 bits.

6
Andrew Mao

Si vous comptez calculer de nombreuses combinaisons comme celle-ci, le calcul du triangle de Pascal est certainement la meilleure option. Comme vous connaissez déjà la formule récursive, je pense pouvoir coder un code ici:

MAX_N = 100
MAX_K = 100

C = [[1] + [0]*MAX_K for i in range(MAX_N+1)]

for i in range(1, MAX_N+1):
    for j in range(1, MAX_K+1):
        C[i][j] = C[i-1][j-1] + C[i-1][j];

print C[10][2]
print C[10][8]
print C[10][3]
4
Juan Lopes

Le moyen le plus rapide est probablement d'utiliser la formule et non pas le triangle Pascal. Commençons par ne pas multiplier quand nous savons que nous diviserons par le même nombre plus tard .. Si k <n/2, ayons k = n - k. Nous savons que C (n, k) = C (n, n-k) Maintenant:

n! / (k! x (n-k)!) = (product of numbers between (k+1) and n) / (n-k)!

Au moins avec cette technique, vous ne divisez jamais par un nombre que vous aviez auparavant multiplié. Vous avez (n-k) multiplications et (n-k) divisions.

Je réfléchis à un moyen d’éviter toutes les divisions en calculant les écarts de gestion entre les nombres que nous devons multiplier et ceux que nous devons diviser. Je vais essayer de modifier plus tard.

1
bruce_ricard

Si vous avez une table de correspondance des factorielles, le calcul de C (n, k) sera très rapide.

0
Andrew Morton