Feedback on Sets, and Partitions

Anton Vredegoor anton at vredegoor.doge.nl
Fri Apr 30 14:33:32 EDT 2004


eadorio at yahoo.com (Ernie) wrote:

>I have an implementation done  in python, not using sets but rather an
>array of integers which can be used for indexing, for processing
>equivalences and set partitions (See
>http://www.geocities.com/eadorio/equiv.pdf).

Thanks.

Here's something I wrote in 2000. I just did some very superficial
inspection of the code and adapted a few names that would not be ok
anymore, now that we have sets, but very likely I would do things very
differently now.

It might start off other implementations though so I'm providing it
below here.

# SetPart.py : return a set divided into subsets. The possible ways
# this can be done are indexed. Algorithms are adapted from the book
# "Combinatorial Algorithms..." (1999) by Donald Kreher and 
# Douglas Stinson.
# See also: http://www.math.mtu.edu/~kreher/cages.html
# Translated and adapted for Python by Anton Vredegoor:
# anton at vredegoor.doge.nl 19 jun 2000
# last update: april 2004

class SetPart:

    def __init__(self, aset):
        self.aset = aset
        self.m = len(self.aset)
        self.d = self.GeneralizedRGF(self.m)
        self.count = self.d[self.m][0]
 
    def __getitem__(self, index):
        # Partition number index
        if index > self.count - 1:
             raise IndexError 
        rgf =  self.UnrankRGF(self.m, index)
        result = self.RGFToSetPart(self.m, rgf, self.aset)
        return result[1:]

## **  Algorithm 3.12
    def RGFToSetPart(self, m, b, aset):
        # Transform a restricted growth function list into a partition
        A = []
        n = 1
        for i in range(1,m+1):
            if b[i] > n:
                n = b[i]
        for i in range(n+1):
            A.append([])
        for i in range(1,m+1):
            A[b[i]].append(aset[i-1])
        return A
            
## **  Algorithm 3.14
    def GeneralizedRGF(self, m):
        # Compute the values d[i.j]
        d = [[1L] * (m+1) for i in range(m+1)]
        for i in range(1,m+1):
            for j in range(0,m-i+1):
                d[i][j] = j * d[i-1][j] + d[i-1][j+1]
        return d

##**  Algorithm 3.16    
    def UnrankRGF(self, m, r):
        # Unrank a restricted grow function
        f = [1] * (m+1)
        j = 1
        d = self.d
        for i in range(2,m+1):
            v = d[m-i][j]
            cr = j*v
            if cr <= r:
                f[i] = j + 1
                r -= cr
                j += 1
            else:
                f[i] = r / v + 1
                r  %= v
        return f

def test():
    aset = range(5)
    P = SetPart(aset)
    print P.count
    for x in P:
         print x

if __name__ == '__main__':
    test()

Anton



More information about the Python-list mailing list