我有一组对象。我还有一组必需的对象,包含0到3个对象。我正在尝试从初始集中找到包含所需对象的3个对象的所有组合。
编辑:示例 -
objects: {A,B,C,D,E}
required: {A}
output: {A,B,C}, {A,B,D}, {A,B,E}, {A,C,D}, {A,C,E}, {A,D,E}
objects: {A,B,C,D,E}
required: {A,B}
output: {A,B,C}, {A,B,D}, {A,B,E}
明显但缓慢的解决方案如下:
for(int i = 0; i < objects.size()-2 ; i++){
for(int j = i; j < objects.size()-1 ; j++){
for(int k = j; k < objects.size() ; k++){
if(required.contains(i) || required.contains (j) || required.contains(k)){
results.add(new Result(i,j,k));
}
}
}
}
无论所需对象如何,此解决方案都会遍历整个搜索空间。
我提出的另一种方法是为每个必需对象编写自定义代码:
switch (required.size()){
case 3:
results.add(new Result(required));
break;
case 2:
Object a = requiredIngredients.toArray()[0];
Object b = requiredIngredients.toArray()[1];
for(Object o : objects){
if(!required.contains(i)){
results.add(new Result(EnumSet.of(o, a, b)));
}
}
break;
等。
这是有效的,但是令人讨厌而且不可推广。
第三种方法是制作三个独立的集合,如果存在需求,则缩小集合仅包括所需的值,然后通常迭代它们:
for(Object i : firstObjects){
for(Object j : secondObjects){
if(i == j) continue;
for(Object k : thirdObjects){
if(j == k) continue;
results.add(new Result(i,j,k));
}
}
}
这似乎有点好,但会产生重复的组合。例如。它会将ABC和ACB作为两个单独的结果返回。我可以让结果集识别重复项,但我不想先计算它。
希望这些例子能够清楚地解决问题。我觉得有人已经想出如何解决这类问题,但我很难确定广义问题类型。
答案 0 :(得分:0)
这是一种简单而通用的方法,但也许不是最有效的(在python中):
from itertools import combinations
def combinations_including(n,objects,required):
extra=objects-required
return sorted([sorted(tuple(required)+x) for x in combinations(extra,n-len(required))])
print combinations_including(3,set('ABCDE'),set('A'))
print combinations_including(3,set('ABCDE'),set('AB'))
输出
[['A', 'B', 'C'], ['A', 'B', 'D'], ['A', 'B', 'E'], ['A', 'C', 'D'], ['A', 'C', 'E'], ['A', 'D', 'E']]
[['A', 'B', 'C'], ['A', 'B', 'D'], ['A', 'B', 'E']]
如果所需的设置很小,那么它可能比蛮力更糟,但随着所需设置的大小增加,它将变得比蛮力更有效。例如,如果所需的集与输入集相同,则它会在恒定时间内找到答案。