有人可以在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}
和
U={1,2,3,4,5,6,7,8,9,10}
程序将找到该组的所有组合,并找出共同具有U的所有元素的最小组数。
在上面的例子中,最小数字是2. set b和e一起覆盖了U的全部。
所以基本上,它是一个集合覆盖问题。在Set Covering问题中,我们给出了一个Universe U,例如|U|=n
和集S1,……,Sk
是U的子集。集合封面是来自{{1}的一些集合的集合C.其联盟是整个宇宙U.此外,我们必须最小化集合的成本。
答案 0 :(得分:4)
您需要的是测试不断增加的组合大小,例如
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;
}
打印
The shortest combination was [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
答案 1 :(得分:1)
由于您需要最佳解决方案,并且由于set cover是NP完全的,因此只需通过强力生成所有可能的组合。对于n
集的输入,将有2^n - 1
种可能的组合。您可以依次生成每个组合:
let the input sets be S1, S2, ..., Sn let min = { S1, S2, ..., Sn } // initially assume all sets are required for i = 1, 2, ..., 2^n - 2 let X = {} represent i as a binary number containing n bits for each bit j that is set to 1, include set Sj in X if X covers all sets and #X < #min update min = X end
答案 2 :(得分:1)
对于迟到的回复感到抱歉。但是如果您仍然对此感兴趣,可以使用Rajagopalan-Vazirani算法获得近似解决方案来设置封面:http://portal.acm.org/citation.cfm?id=299880。这将为您提供最多距离最佳因素2的答案。
答案 3 :(得分:0)
让I
代表到目前为止包含的元素集。
初始化I = {}
在I
与U
不同的情况下执行关注
Si
中找到成本效益最小的集合{S1, S2, ... Sm}
。Si
的元素添加到I
,即I = I U Si
。