Combinations (was Re: Permutations algoritm?)
Anton Vredegoor
anton at vredegoor.doge.nl
Sat Nov 16 06:40:37 EST 2002
On Fri, 15 Nov 2002 15:51:04 -0600, sismex01 at hebmex.com wrote:
>Of a set of different items 'S', obtain all distinct subsets of 'n'
>items where all items in the subset are different.
>
>So, if I have, for example:
>
> S = [ 0, 1, 2, 3 ]
>
>the universe of available subsets of 3 items would be:
>
> s = [ (0, 1, 2),
> (0, 1, 3),
> (0, 2, 3),
> (1, 2, 3) ]
>
>the universe of available subsets of 2 items would be:
>
> s = [ (0, 1),
> (0, 2),
> (0, 3),
> (1, 2),
> (1, 3),
> (2, 3) ]
In order to make the title conform to what is described above, I had
to start a new thread, I hope you will find it!
Below is my current state of the art combinations algo, I would
welcome improvements. It's a bit long perhaps, but its supports
indexed combinations and can index large sets.
Regards,
Anton.
class combinations:
def __init__(self,n,k):
self.n,self.k = n,k
self.count = self.noverk(n,k)
def __getitem__(self,index):
#combination number index
if index > self.count - 1:
raise IndexError
result = []
pos,n,k = 0,self.n,self.k
treshold = self.treshold
for i in range(k):
offset, index = treshold(index,n-i-pos,k-i)
pos += offset
result.append(pos+i)
return result
def noverk(self,n,k):
#compute n over k
result = 1l
for i in range(k):
result = result*(n-i)/(i+1)
return result
def treshold(self,val,n,k):
#cumulative treshold on a diagonal of pascals triangle
cum,tresh,rest = 0,0,0
noverk = self.noverk
for i in range(n-k+1):
x = noverk(n-i-1,k-1)
cum += x
if cum > val:
rest = val + x - cum
break
tresh += 1
return tresh, rest
def test():
comb = combinations(4,2)
print comb.count
for c in comb:
print c
if __name__ == '__main__':
test()
More information about the Python-list
mailing list