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]]
我有 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]]