Calculate value of n choose k [closed]

寵の児 提交于 2019-12-17 08:21:06

问题


What is the most efficient method to evaluate the value of n choose k ? The brute force way I think would be to find n factorial / k factorial / (n-k) factorial .

A better strategy may be to use dp according to this recursive formula. Is there any other better method to evaluate n choose k ?


回答1:


You could use the Multiplicative formula for this:

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




回答2:


Here is my version, which works purely in integers (the division by k always produces an integer quotient) and is fast at O(k):

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

I wrote it recursively because it's so simple and pretty, but you could transform it to an iterative solution if you like.




回答3:


Probably the easiest way to compute binomial coefficients (n choose k) without overflowing is to use Pascal's triangle. No fractions or multiplications are necessary. (n choose k). The nth row and kth entry of Pascal's triangle gives the value.

Take a look at this page. This is an O(n^2) operation with only addition, which you can solve with dynamic programming. It's going to be lightning fast for any number that can fit in a 64-bit integer.




回答4:


If you're going to calculate many combinations like this, calculating the Pascal's Triangle is sure the best option. As you already know the recursive formula, I think I can past some code here:

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]



回答5:


The problem with the n!/k!(n-k)! approach is not so much the cost as the issue with ! growing very rapidly so that, even for values of nCk which are well within the scope of, say, 64-bit integers, intermediate calculations are not. If you don't like kainaw's recursive addition approach you could try the multiplicative approach:

nCk == product(i=1..k) (n-(k-i))/i

where product(i=1..k) means the product of all the terms when i takes the values 1,2,...,k.




回答6:


The fastest way is probably to use the formula, and not pascals triangle. Let's start not to do multiplications when we know that we're going to divide by the same number later. If k < n/2, let's have k = n - k. We know that C(n,k) = C(n,n-k) Now :

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

At least with this technique, you're never dividing by a number that you used to multiply before. You have (n-k) multiplications, and (n-k) divisions.

I'm thinking about a way to avoid all divisions, by finding GCDs between the numbers that we have to multiply, and those we have to divide. I'll try to edit later.




回答7:


If you have a lookup table of factorials then the calculation of C(n,k) will be very fast.




回答8:


"Most efficient" is a poor request. What are you trying to make efficient? The stack? Memory? Speed? Overall, my opinion is that the recursive method is most efficient because it only uses addition (a cheap operation) and the recursion won't be too bad for most cases. The function is:

nchoosek(n, k)
{
    if(k==0) return 1;
    if(n==0) return 0;
    return nchoosek(n-1, k-1)+nchoosek(n-1,k);
}


来源:https://stackoverflow.com/questions/15301885/calculate-value-of-n-choose-k

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!