Reputation: 2976
Given a collection of numbers that may contain duplicates, find all partitions of it. (all possible ways of dividing the collection.)
For instance, the multiset {1, 1, 2} has 4 partitions:
partition 1 = { {1}, {1}, {2} } partition 2 = { {1}, {1, 2} } partition 3 = { {1, 1}, {2} } partition 4 = { {1, 1, 2} }
Here is a similar question How to find all partitions of a set but in that question, all numbers are distinct.
Definition for set partitions: https://en.wikipedia.org/wiki/Partition_of_a_set
Definition for multiset: https://en.wikipedia.org/wiki/Multiset
A solution written in any common programming language with some explanation will be greatly appreciated.
Update:
Seems like a lot of people are confused what the question is asking about. It's NOT asking for all the possible subsets of the given collection. Rather, it's asking you to find out all the different ways of dividing the given collection of numbers.
Upvotes: 6
Views: 1410
Reputation: 1106
Hey I do have a python solution:
from sympy.utilities.iterables import multiset_partitions
for pi in multiset_partitions([1,1,3]):
print(pi)
Looking at the code, you can find the algorithm in Knuth's AOCP
Algorithm M, page 39-40.
The AOCP is also described here
Refer to Volume 3b, Algorithm M, page 39-40.
Upvotes: 4
Reputation: 570
It's a Partition set problem.
Number of elements in the original set always equals to the sum of number of elements in each partition.
It can be solved using backtracking and recursion. This C++ program might be useful.
void solve (set<vector<vector<int>>>& solution, vector<int> inputSet,
vector<vector<int>>& partitions, vector<int> partition, int n, int i) {
int numberOfElements = 0;
for (int i=0; i<partitions.size(); i++) {
numberOfElements += partitions[i].size();
}
if (numberOfElements == n) {
vector<vector<int>> newPartitions = partitions;
for (int i=0; i<newPartitions.size(); i++) {
sort (newPartitions[i].begin(), newPartitions[i].end());
}
sort(newPartitions.begin(), newPartitions.end());
solution.insert(newPartitions);
return;
}
for (int j=i; j<n; j++) {
partition.push_back(inputSet[j]);
partitions.push_back(partition);
vector<int> partitionNew;
solve(solution, inputSet, partitions, partitionNew, n, j+1);
partitions.pop_back();
}
}
void permute (set<vector<vector<int>>>& solution, vector<int>& inputSet, int i, int n) {
if (i == n) {
vector<int> partition;
vector<vector<int>> partitions;
solve(solution, inputSet, partitions, partition, inputSet.size(), 0);
return;
}
for (int j=i; j<=n; j++) {
swap(inputSet[i], inputSet[j]);
permute(solution, inputSet, i+1, n);
swap(inputSet[i], inputSet[j]);
}
}
Here's the working example: Generate all Partitions
EDIT: I misread the question. I have updated the answer. It now generates all possible partitions.
Upvotes: -3