#! /usr/bin/env python
def combs1(k, available, used=[]):
if len(used) == k:
yield tuple(used)
elif len(available) <= 0:
pass
else:
for c in combs1(k, available[1:], used[:]+[available[0]]):
yield c
for c in combs1(k, available[1:], used[:]):
yield c
def combs2(k, available, used=[]):
if len(used) == k:
yield tuple(used)
elif len(available) <= 0:
pass
else:
head = available.pop(0)
used.append(head)
for c in combs2(k, available, used):
yield c
used.pop(-1)
for c in combs2(k, available, used):
yield c
available.insert(0, head)
def testfunctions(testlist, k=2):
mycombs = []
testfunctions = [combs1, combs2]
for tf in testfunctions:
mycombs.append([s for s in tf(k, testlist)])
# this is for validation
import itertools
combs_from_lib = [i for i in itertools.combinations(testlist, k)]
results = []
for mycomb in mycombs:
if mycomb == combs_from_lib:
results.append('correct')
else:
results.append('wrong')
return results
if __name__ == '__main__':
print testfunctions(list('abc'))
For validation, I import the itertools.combinations and compare the results from my functions. They match!
mathjax
Tuesday, May 13, 2014
Combinations
A combination is an instance of one possible way to choose k things from n things. For example, all combinations of size 2 from the list ['a', 'b', 'c'] are ['a', 'b'], ['b', 'c'], and ['a', 'c']. The number of combinations is just famed n-choose-k function: $ \binom{n}{k} = \frac{n!}{k!(n-k!)} $. In the example above, n = 3 and k = 2, so the number of combinations is $ \frac{3!}{2!(3-2!)} = \frac{3!}{2! 1!} = \frac{3!}{2!} = \frac{3*2*1}{2*1} = 3 $. The following functions compute all combinations of a list. Each has advantages and disadvantages, depending on your needs. The first function, combs1(), makes copies of the list in the recursive call. This will effect performance for large lists. However, the second function, combs2(), makes no copies, which is why it requires a little more manipulation.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment