0

I am working on a code in Python 2 that partitions a set of 13 elements using integer partitions, then evaluating the different combinations they can have (order does not matter). I have seen the ways people do this by using recursive functions to calculate every partition in a set retroactively, but for what I'm working on I'm taking a different approach.

I'm working with the logic that the different ways a set can be partitioned is determined by the integer partitions of a set. For a set of 4 elements, it can be partitioned in these ways:

[1,1,1,1]
[1,1,2]
[2,2]
[1,3]
[4]

Every number stands for the length of a subset in the partition. Using this info, I can then calculate all of the combinations that can be used with these different integer partitions. If I add the number of combinations from each partition together, I should receive the Bell number (the number of possible partitions in a set). For a list of 4 elements, the Bell number should be 15.

My code runs through the subset lengths in each partition, sets the length of the set to n and the subset length to r, then calculates the combinations in the specific subset. When it goes to the next subset, it subtracts the previous r from n to account for it lessening the amount of combinations available, as n gets smaller when a subset is already defined.

My code, however, is lackluster. When inputting 4 as the length of the set, it outputs 16 (instead of 15). When inputting 5, it outputs 48 (instead of 52). When inputting 13, it outputs 102,513 (instead of 27,644,437). I need it to be exact rather than an estimate.

This is in part because of if elem != 1: not properly accounting for a list of all ones or a list of one subset. It's also in part because it doesn't account for repeats of a combination when appearing in a subset. In [2,2] for a list of 4 elements, it considers the subset to contain 6 combinations when in reality it contains 3.

I'm stuck on how to solve this issue, as I only know enough Python to get by. The way the code currently outputs is how I prefer it to output, obviously without the errors.

The recursive function that calculates the integer partitions is from Nicolas Blanc, and the rest was coded by myself. Important links: Bell number, Partition of a set

import math

in_par = []
stack = []
bell = 0  

def partitions(remainder, start_number = 1):
    if remainder == 0:
        in_par.append(list(stack))
        #print stack
    else:
        for nb_to_add in range(start_number, remainder+1):
            stack.append(nb_to_add)
            partitions(remainder - nb_to_add, nb_to_add)
            stack.pop()

x = partitions(13) # <------- input element count here

for part in in_par:
    part.reverse()
    combinations = 0
    n = 13 # <------- input element count here

    for i,elem in enumerate(part):
        r = elem
        combo = 0
        if elem != 1:
            if i != (len(part) - 1):
                combo = math.factorial(n) / (math.factorial(r) * math.factorial(n-r))
                n = n - elem
        
        combinations = combinations + combo
    
    bell = bell + combinations
    part.append([combinations])
    
    print part
    #print str(bell)

print "Bell Number: " + str(bell)
lordfoog
  • 9
  • 3
  • 2
    "I am working on a code in Python 2" Why? Unless you are maintaining legacy code there isn't any good reason to be coding in Python 2 after it has been retired. – John Coleman Jan 18 '23 at 16:20
  • @JohnColeman probably school assignment. – Thomas Matecki Jan 18 '23 at 16:24
  • @JohnColeman I believe the only reason for this was because I was annoyed that Python 3 requires you put parentheses in a print statement. When I first learned coding I started in Python 2 so it's easier for the time being. It's the smallest annoyance but that's what I prefer for now. – lordfoog Jan 18 '23 at 16:26
  • @ThomasMatecki The reason I'm using Python 2 is in fact because of school, but I'm doing this for a project of my own – lordfoog Jan 18 '23 at 16:27

0 Answers0