Improve this recursive code please!
Anton Vredegoor
anton at vredegoor.doge.nl
Wed May 7 04:52:23 EDT 2003
#! /usr/bin/env python
"""
Function bins returns a list with all possible ways of distributing
m bricks into n bins. The partition code is based on pseudo code
from Kreher and Stinson.
"""
def starters(L):
#helper function for anagram, returns a list of 2-tuples
n,np,R = len(L),1,range(len(L))
bf = [L[:i].count(L[i]) for i in R]
for i in R: np = np*(n-i)/(bf[i]+1)
return [(i,np*L[i:].count(L[i])/n) for i in R if not bf[i]]
def anagram(L,index=0):
#return an anagram of list L
remain, res, T = index, [], L[:]
while T:
for j,k in starters(T):
if remain-k < 0:
res.append(T.pop(j))
break
remain -= k
return res
def nperm(L):
#return the number of possible anagrams of list L
return reduce(lambda a,b:a+b,[k for j,k in starters(L)])
class Partition:
#helper class for partition information
def __init__(self,m):
self.m = m
self.parts = [0]*(m+1)
def dump(self,numparts):
return [ self.parts[i] for i in range(1,numparts+1)]
def recPartition(a,m,B,N,accu=[]):
# helper function generates all partitions of m
if m == 0:
accu.append(a.dump(N))
else:
for i in range(1, min([B,m])+1):
a.parts[N+1] = i
recPartition(a,m-i,i,N+1,accu)
return accu
def genPartitions(m,n):
# generates a list of all partitions of m into at most n parts
a = Partition(m)
return [x for x in recPartition(a,m,m,0) if len(x) <= n]
def bins(m,n):
#all possible ways to distribute m bricks into n bins
res = []
for p in genPartitions(m,n):
while len(p)< n: p+=[0]
for i in range(nperm(p)): res.append(anagram(p,i))
return res
def test():
#test function bins
numbricks, numbins = 3,4
bb = bins(numbricks, numbins)
print len(bb)
for x in bb:
print x
if __name__ == '__main__':
test()
output:
>d:\python23\pythonw -u bins.py
20
[1, 1, 1, 0]
[1, 1, 0, 1]
[1, 0, 1, 1]
[0, 1, 1, 1]
[2, 1, 0, 0]
[2, 0, 1, 0]
[2, 0, 0, 1]
[1, 2, 0, 0]
[1, 0, 2, 0]
[1, 0, 0, 2]
[0, 2, 1, 0]
[0, 2, 0, 1]
[0, 1, 2, 0]
[0, 1, 0, 2]
[0, 0, 2, 1]
[0, 0, 1, 2]
[3, 0, 0, 0]
[0, 3, 0, 0]
[0, 0, 3, 0]
[0, 0, 0, 3]
>Exit code: 0
More information about the Python-list
mailing list