Разделите набор на все возможные подмножества, которые включены в данный список - PullRequest
0 голосов
/ 11 марта 2019

Учитывая список определенных подмножеств, таких как

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 секунд и это число становится геометрическим
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...