在Julia中生成具有两个值的项目的所有组合



我有m项。每个项目是一对两个值。例如,对于m=4,我有一个矩阵:

julia> valid_pairs = [0 1;
1 2;
1 2;
2 3];

我想生成四个项目的所有组合,其中每个项目i只能取valid_pairs[i, :]中的值。基于前面的例子,我想要:

julia> all_combs
4x16 Array{Int,2}
0  0  0  0  0  0  0  0  1  1  1  1  1  1  1  1
1  1  1  1  2  2  2  2  1  1  1  1  2  2  2  2
1  1  2  2  1  1  2  2  1  1  2  2  1  1  2  2
2  3  2  3  2  3  2  3  2  3  2  3  2  3  2  3

我觉得使用Combinatorics.jl可以很容易地做到这一点。

虽然我使用了Combinatorics.jl,但我所做的是:

using Combinatorics
m = 4
combs = combinations(1:m) |> collect
L = length(combs)
all_combs = zeros(Int, m, L+1)
for j in 1:L
for i in 1:m
if !in(i, combs[j])
all_combs[i, j] = valid_pairs[i, 1]
else
all_combs[i, j] = valid_pairs[i, 2]
end
end
end
all_combs[:, end] = valid_pairs[:, 1]

不是相同的订单,而是

julia> [collect(x) for x in Iterators.product(eachrow(valid_pairs)...)]
2×2×2×2 Array{Array{Int64,1},4}:
[:, :, 1, 1] =
[0, 1, 1, 2]  [0, 2, 1, 2]
[1, 1, 1, 2]  [1, 2, 1, 2]
[:, :, 2, 1] =
[0, 1, 2, 2]  [0, 2, 2, 2]
[1, 1, 2, 2]  [1, 2, 2, 2]
[:, :, 1, 2] =
[0, 1, 1, 3]  [0, 2, 1, 3]
[1, 1, 1, 3]  [1, 2, 1, 3]
[:, :, 2, 2] =
[0, 1, 2, 3]  [0, 2, 2, 3]
[1, 1, 2, 3]  [1, 2, 2, 3]

如果你真的想要一个矩阵(2D阵列(,那么你可以hcat前面的答案,或者直接做

julia> reduce(hcat, collect(x) for x in Iterators.product(eachrow(valid_pairs)...))
4×16 Array{Int64,2}:
0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1
1  1  2  2  1  1  2  2  1  1  2  2  1  1  2  2
1  1  1  1  2  2  2  2  1  1  1  1  2  2  2  2
2  2  2  2  2  2  2  2  3  3  3  3  3  3  3  3

EDIT:附带说明,我会将对定义为元组,以澄清发生了什么,所以类似

valid_pairs = [(0,1), (1,2), (1,2), (2,3)]

我不会创建2D(或4D,或m-D(阵列,而是做

comb_pairs = Iterators.product(valid_pairs...)

然后,它为您提供了所有对组合的lazy版本,这样您就可以在不首先实际创建的情况下对其进行迭代,我认为这应该更高效(看起来更干净(。

最新更新