I have a set of distinct values. I am looking for a way to generate all partitions of this set, i.e. all possible ways of dividing the set into subsets.
For instance, the set {1, 2, 3}
has the following partitions:
{ {1}, {2}, {3} },
{ {1, 2}, {3} },
{ {1, 3}, {2} },
{ {1}, {2, 3} },
{ {1, 2, 3} }.
As these are sets in the mathematical sense, order is irrelevant. For instance, {1, 2}, {3}
is the same as {3}, {2, 1}
and should not be a separate result.
A thorough definition of set partitions can be found on Wikipedia.
Please refer to the Bell number, here is a brief thought to this problem:
consider f(n,m) as partition a set of n element into m non-empty sets.
For example, the partition of a set of 3 elements can be:
1) set size 1: {{1,2,3}, } <-- f(3,1)
2) set size 2: {{1,2},{3}}, {{1,3},{2}}, {{2,3},{1}} <-- f(3,2)
3) set size 3: {{1}, {2}, {3}} <-- f(3,3)
Now let's calculate f(4,2):
there are two ways to make f(4,2):
A. add a set to f(3,1), which will convert from {{1,2,3}, } to {{1,2,3}, {4}}
B. add 4 to any of set of f(3,2), which will convert from
{{1,2},{3}}, {{1,3},{2}}, {{2,3},{1}}
to
{{1,2,4},{3}}, {{1,2},{3,4}}
{{1,3,4},{2}}, {{1,3},{2,4}}
{{2,3,4},{1}}, {{2,3},{1,4}}
So
f(4,2) = f(3,1) + f(3,2)*2
which result in
f(n,m) = f(n-1,m-1) + f(n-1,m)*m
Here is Java code for get all partitions of set:
And result is:
[[[1, 2, 3]]] [[[1, 3], [2]], [[1], [2, 3]], [[1, 2], [3]]] [[[1], [2], [3]]] Number of partitions: 5
Here is a solution in Ruby that's about 20 lines long:
(I'm not trying to shill for Ruby, I just figured that this solution may easier for some readers to understand.)
Just for fun, here's a shorter purely iterative version:
Test here:https://ideone.com/EccB5n
And a simpler recursive version:
https://ideone.com/Kdir4e
A trick I used for a set of N members. 1. Calculate 2^N 2. Write each number between 1 and N in binary. 3. You will get 2^N binary numbers each of length N and each number tells you how to split the set into subset A and B. If the k'th digit is 0 then put the k'th element in set A otherwise put it in set B.
I've found a straightforward recursive solution.
First, let's solve a simpler problem: how to find all partitions consisting of exactly two parts. For an n-element set, we can count an int from 0 to (2^n)-1. This creates every n-bit pattern, with each bit corresponding to one input element. If the bit is 0, we place the element in the first part; if it is 1, the element is placed in the second part. This leaves one problem: For each partition, we'll get a duplicate result where the two parts are swapped. To remedy this, we'll always place the first element into the first part. We then only distribute the remaining n-1 elements by counting from 0 to (2^(n-1))-1.
Now that we can partition a set into two parts, we can write a recursive function that solves the rest of the problem. The function starts off with the original set and finds all two-part-partitions. For each of these partitions, it recursively finds all ways to partition the second part into two parts, yielding all three-part partitions. It then divides the last part of each of these partitions to generate all four-part partitions, and so on.
The following is an implementation in C#. Calling
yields
Here is a non-recursive solution