Thread: Combinations
View Single Post
Old Jun 7th, 2005, 7:14 AM   #1
Gilward Kukel
Newbie
 
Join Date: Jun 2005
Location: Vienna, Austria
Posts: 15
Rep Power: 0 Gilward Kukel is on a distinguished road
Smile Combinations

Here are two functions that I wrote:
comb_count(n, k) returns the number of k-combinations of n elements.
comb_list(seq, k) returns a list of all k-combinations of the elements of sequence seq.
So comb_count(n,k) gives the same result as len(comb_list(seq,k)) when len(seq)==n

More about combinations:
http://en.wikipedia.org/wiki/Combination
http://www.theory.csc.uvic.ca/~cos/i...tionsInfo.html
http://mathworld.wolfram.com/Combination.html
http://web.hamline.edu/~lcopes/SciMa...pts/ccomb.html

Example usage:
>>> comb_count(5,3)
10
>>> comb_list(range(0,5),3)
[[0, 1, 2], [0, 1, 3], [0, 1, 4], [0, 2, 3], [0, 2, 4],
 [0, 3, 4], [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]
>>> len(_)
10

function definitions:
def comb_count(n, k):
    "returns the number of k-combinations of n elements"
    if n<0 or k<0 or n!=long(n) or k!=long(k):
        raise Exception,"n and k should be nonnegative integers"
    if n<k:
        return 0
    elif n==k:
        return 1
    if k>n/2:
        k=n-k
    h=1
    for i in range (1,k+1):
        h*=n-i+1
        h/=i
    return h

def comb_list(seq, k):
    "returns a list of all k-combinations of the elements of sequence seq"
    n=len(seq)
    if not 0<=k<=n:
        raise Exception,"0<=k<=len(seq) is not true"
    v=[]   #list of combinations
    #x: number of taken elements
    #y: number of rejected elements
    #we want to take k elements and reject n-k elements
    def f(x,y,a):
        if x==k:
            #we have taken enough elements, reject all remaining elements
            v.append(a)
            return
        if y==n-k:
            #we have rejected enough elements, take all remaining elements
            a.extend(seq[x+y:])
            v.append(a)
            return
        if (x<k):
            #take element seq[x+y]
            h=a+[seq[x+y]]
            f(x+1,y,h)
        if (y<n-k):
            #don't take element seq[x+y]
            f(x,y+1,a)            
    f(0,0,[])
    return v
There are probably better algorithms for this but I'm glad I was able to write at least a correct algorithm.

Last edited by Gilward Kukel; Jun 7th, 2005 at 2:47 PM.
Gilward Kukel is offline   Reply With Quote