|
Newbie
Join Date: Jun 2005
Location: Vienna, Austria
Posts: 15
Rep Power: 0 
|
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.
|