returns 为多个变量设置所有可能组合的伪代码或 C# 算法

Pseudocode or C# algorithm that returns all possible combinations sets for a number of variables

我有 3 个具有一些可能值的变量。 例如:

Var1 - possible values: 1,2,3
Var2 - possible values: a, b, c 
var3 - possible values: false, true

能否请您提供一种 returns 所有可能组合的方法?

结果如下:

   1,a,false
   1,a,true,
   1,b,false
   1,b,true,
   1,c,false
   1,c,true
   2,a,false
   2,a,true
   2,b,false
   Etc..

我希望该算法可以应用于任何级别的组合,例如,该算法适用于具有其他可能值的 4 或 5 个变量。

假设每个变量都有一个与 is 关联的集合或向量。那是: set1 = [1, 2, 3] set2 = [a, b, c] set3 = [F, T]

然后,一种方法是在嵌套的 "for" 循环中遍历这些集合。假设您的输出结构是 3 元素列表的列表。也就是说,您想要的输出如下所示: [[1,a,F], [1,a,T], [1,b,F],......] 还假设(就像在 Python 中一样)您可以使用像 "append" 这样的函数将 2 元素列表附加到您的大列表中。然后试试这个:

myList = []  #empty list
for i in set1:
  for j in set2:
    for k in set3:
      myList.append([i, j, k])  #Appends 3-element list to big list

您可能需要在追加语句中进行深层复制,这样每次 运行 迭代时,您的主列表中的所有 i、j 和 k 都不会更新。这可能不是最有效的,但我认为它相对简单。

最简单的解决方案是有 n 个嵌套循环:

for each possible value v1 in var1
    for each possible value v2 in var2
        for each possible value v3 in var3
            print(v1,v2,v3);
        end for v3
    end for v2
end for v1

在更一般的情况下,假设您有包含 n 个列表(每个变量一个)的列表列表,并且每个列表都包含每个变量的可能值。您可以使用以下递归函数解决问题 all_combinations.

list_of_lists=[[1...][a...][false...]];
current_comb=[];

all_combinations(list_of_lists,current_comb);

function all_combinations(list_of_lists,current_comb)
    if (list_of_lists=[])
        print(current_comb);
        return;
    end if
    current_list=list_of_lists[0];
    remaining_lists=list_of_lists[1:end];
    for each v in current_list
        tmp=current_comb;tmp.Append(v);
        all_combinations(remaining_lists,tmp);
    end for v

当然在添加变量的时候,很快就需要处理组合爆炸了

您似乎在尝试枚举 Cartesian products。假设您的项目在 list_of_lists 中,这个伪代码中的递归函数将执行此操作:

enumerate_cartesian_prducts(list_of_lists):

    if list_of_lists is empty:
        return [[]]

    this_list = list_of_lists[0]
    other_lists = list_of_lists[1: ]
    other_cartesian_products = []
    return [(e + other_cartesian_product) \
        for e in this_list and other_cartesian_product in other_cartesian_products]

注意最后一行在大多数语言中可能是一个双循环:它遍历第一个列表中的所有元素,其余列表的笛卡尔积中的所有列表,并创建一个包含所有附加元素的列表结果。

唯一干净的解决方案是:

有一个函数 mix( A, B ),它接受两个列表,returns 接受一个列表。那是微不足道的。

您的最终代码如下所示:

result = null
result = mix( result, one of your lists );
result = mix( result, another of your lists );
result = mix( result, yet another of your lists );
result = mix( result, yet another list );
result = mix( result, one more list );

混合示例(A,B) ...

mix(A,B)
result = null
for each A
  for each B
    result += AB
return result

你真的应该在别处寻找这个,这不是一个很好的 Whosebug 问题。这是家庭作业,如果您使用适当的术语进行更多搜索,已经有一个算法可以解决这个问题。

其实很简单,如果将生成二进制字符串中所有数字组合的算法概括一下,应该可以得到:

0 0 0 0 
0 0 0 1
0 0 1 0
0 0 1 1
0 1 0 0
0 1 0 1
0 1 1 0
0 1 1 1
1 0 0 0 
1 0 0 1
1 0 1 0
1 0 1 1
1 1 0 0
1 1 0 1
1 1 1 0
1 1 1 1

请注意,最右侧的列每一个单元格交替显示其值,而右数第二列每 2 个单元格交替显示一次,下一列每 4 个单元格交替显示一次,最后一个数字每 8 个单元格交替显示一次.

对于您的情况,请将以上内容视为您的集合是:

Var1 - possible values: 0,1
Var2 - possible values: 0,1
Var3 - possible values: 0,1
Var4 - possible values: 0,1

启动一个计数器来跟踪您在每组中的位置,并开始循环整个 "rightmost" 组,然后将 "next-from-right" 组的位置增加 1。继续循环以这种方式设置集合,当一个集合到达其 "right" 循环时增加一个集合,直到您完成 "most significant position" 中的集合循环。您将生成集合中所有可能的组合。

其他答案都集中在 "give the codez" 上,这真的只是奖励你在这里发布作业问题...所以我想我至少会解释一下。

JavaScript 中有一些类似伪代码的内容。 (我从来没有用 C# 编写过代码;也许我会尝试转换它。)

var sets = [[1,2,3],["a","b","c"],[false,true]],
    result = [];

function f(arr,i){
  if (i == sets.length){
    result.push(arr);
    return;
  }
  for (var j=0; j<sets[i].length; j++){
    _arr = arr.slice(); // make a copy of arr
    _arr.push(sets[i][j]);
    f(_arr,i+1);
  }
}

f([],0)

输出:

console.log(result);

[[1,"a",false]
,[1,"a",true]
,[1,"b",false]
,[1,"b",true]
,[1,"c",false]
,[1,"c",true]
,[2,"a",false]
,[2,"a",true]
,[2,"b",false]
,[2,"b",true]
,[2,"c",false]
,[2,"c",true]
,[3,"a",false]
,[3,"a",true]
,[3,"b",false]
,[3,"b",true]
,[3,"c",false]
,[3,"c",true]]