Учитывая список определенных подмножеств, таких как
S = [ {1}, {2}, {2, 3}, {3}, {4} ]
и набор "вселенная", подобный
U = {1, 2, 3, 4}
Мне нужна функция Java, которая находит все возможные разделы U, сделанные из множеств из S? В этом примере такие разделы включают в себя:
{1} {2} {3} {4}
{1} {2, 3} {4}
и т.д ..
Я нашел похожий пример, который находит все возможные разделы набора, и я настраиваю его так, чтобы он оставлял только те разделы, которые включают в себя заданные подмножества, но, учитывая набор "Universe" из 10 или более чисел, он становится очень медленным ( слишком много возможностей). Вот мой код
private List<List<List<Integer>>> buildFullPartitions(List<Integer> inputSet, List<List<Integer>> subsets)
{
List<List<List<Integer>>> partitions = new ArrayList<>();
if (inputSet.isEmpty()) {
List<List<Integer>> empty = new ArrayList<>();
partitions.add(empty);
return partitions;
}
int limit = 1 << (inputSet.size() - 1);
for(int j = 0; j < limit; ++j) {
List<List<Integer>> parts = new ArrayList<>();
List<Integer> part1 = new ArrayList<>();
List<Integer> part2 = new ArrayList<>();
parts.add(part1);
parts.add(part2);
int i = j;
for(int item : inputSet) {
parts.get(i&1).add(item);
i >>= 1;
}
for(List<List<Integer>> b : buildFullPartitions(part2))
{
List<List<Integer>> holder = new ArrayList<>();
holder.add(part1);
holder.addAll(b);
int matchedParts = 0;
for(List<Integer> particle : holder) {
for(List<Integer> subset : subsets) {
if(particle.equals(subset))) {
matchedParts++;
}
}
if(matchedParts == holder.size())
partitions.add(holder);
}
}
}
return partitions;
}
Любое предложение о том, как улучшить это, не ища все возможные разделы, а только те, которые содержат только данные подмножества?
В ответ на комментарии я отредактировал свой код, чтобы было более понятно, что я делаю.
Я профилирую свой код с разными наборами "юниверсов" разной длины, и в результате получается:
- 12 длина ---> 30 секунд
- 13 длина ---> 208 секунд
и это число становится геометрическим