找到所有套装的组合 - 套装封面?

sap*_*sap 2 java algorithm

有人可以在java中分享一个程序,它执行以下操作。如果给定以下集合作为输入,

a={1,2,3,8,9,10}
b={1,2,3,4,5}
c={4,5,7}
d={5,6,7}
e={6,7,8,9,10}
Run Code Online (Sandbox Code Playgroud)

U={1,2,3,4,5,6,7,8,9,10}
Run Code Online (Sandbox Code Playgroud)

程序将找到集合的所有组合,并找出集合在一起具有 U 的所有元素的最小集合数。

在上面的例子中,最小数是2。集合b和e一起覆盖了所有的U。所以基本上,这是一个集合覆盖问题。在集合覆盖问题中,我们给定了一个宇宙 U,使得|U|=n,并且集合S1,……,Sk是 U 的子集。一个集合覆盖是一些集合的集合 C,S1,……,Sk它的并集是整个宇宙 U。此外,我们必须最小化套装的成本。

Pet*_*rey 5

您需要的是测试不断增加的组合大小,就像这样

interface Filter<T> {
    boolean matches(T t);
}
public static void main(String... args) throws IOException {
    Integer[][] arrayOfSets = {
            {1, 2, 3, 8, 9, 10},
            {1, 2, 3, 4, 5},
            {4, 5, 7},
            {5, 6, 7},
            {6, 7, 8, 9, 10},
    };
    Integer[] solution = {1,2,3,4,5,6,7,8,9,10};

    List<Set<Integer>> listOfSets = new ArrayList<Set<Integer>>();
    for (Integer[] array : arrayOfSets)
        listOfSets.add(new LinkedHashSet<Integer>(Arrays.asList(array)));
    final Set<Integer> solutionSet = new LinkedHashSet<Integer>(Arrays.asList(solution));

    Filter<Set<Set<Integer>>> filter = new Filter<Set<Set<Integer>>>() {
        public boolean matches(Set<Set<Integer>> integers) {
            Set<Integer> union = new LinkedHashSet<Integer>();
            for (Set<Integer> ints : integers)
                union.addAll(ints);
            return union.equals(solutionSet);
        }
    };

    Set<Set<Integer>> firstSolution = shortestCombination(filter, listOfSets);
    System.out.println("The shortest combination was "+firstSolution);
}

private static <T> Set<T> shortestCombination(Filter<Set<T>> filter, List<T> listOfSets) {
    final int size = listOfSets.size();
    if (size > 20) throw new IllegalArgumentException("Too many combinations");
    int combinations = 1 << size;
    List<Set<T>> possibleSolutions = new ArrayList<Set<T>>();
    for(int l = 0;l<combinations;l++) {
        Set<T> combination = new LinkedHashSet<T>();
        for(int j=0;j<size;j++) {
            if (((l >> j) & 1) != 0)
                combination.add(listOfSets.get(j));
        }
        possibleSolutions.add(combination);
    }
    // the possible solutions in order of size.
    Collections.sort(possibleSolutions, new Comparator<Set<T>>() {
        public int compare(Set<T> o1, Set<T> o2) {
            return o1.size()-o2.size();
        }
    });
    for (Set<T> possibleSolution : possibleSolutions) {
        if (filter.matches(possibleSolution))
            return possibleSolution;
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

印刷

The shortest combination was [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
Run Code Online (Sandbox Code Playgroud)