查找包含所需值的组合

时间:2012-08-30 04:38:35

标签: algorithm set

我有一组对象。我还有一组必需的对象,包含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作为两个单独的结果返回。我可以让结果集识别重复项,但我不想先计算它。

希望这些例子能够清楚地解决问题。我觉得有人已经想出如何解决这类问题,但我很难确定广义问题类型。

1 个答案:

答案 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']]

如果所需的设置很小,那么它可能比蛮力更糟,但随着所需设置的大小增加,它将变得比蛮力更有效。例如,如果所需的集与输入集相同,则它会在恒定时间内找到答案。