将集合划分为给定列表中包括的所有可能子集

时间:2019-03-11 10:39:48

标签: java subset partitioning

给出特定子集的列表,例如

S = [ {1}, {2}, {2, 3}, {3}, {4} ]

和“宇宙”设置

U = {1, 2, 3, 4}

我需要一个Java函数,该函数从S中查找由集合构成的U的所有可能分区?在此示例中,此类分区包括:

{1} {2} {3} {4}

{1} {2, 3} {4}

等等。

我找到了一个类似的示例,该示例找到了集合的所有可能分区,并且对其进行了调整,以仅保留那些包含给定子集的分区,但是给定一个由10个或更多数字组成的“ Universe”集,它会变得非常慢(太多的可能性)。这是我的代码

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;
}

关于不通过查找所有可能的分区而是仅查找仅包含给定子集的分区的方法来提出改进建议吗?

为回应评论,我编辑了代码以更清楚地了解我在做什么。 我分析了我的代码,并使用了不同长度的不同“ Universe”集,结果是:

  • 12长---> 30秒
  • 13个长度---> 208秒 而且这个数字呈几何形状增长

0 个答案:

没有答案