Julia 所有可能的排列
问题描述
我有一个3×3的矩阵,其元素可以取值为-1、0或1。我想要得到所有可能的排列,所以结果的总数(所有的3×3矩阵)应该是3^(3*3)=19683。
例如结果:[[0,-1,-1],[-1,1,0],[0,0,1]]
我试过使用combinatorics.jl包,但它仅适用于组合,而不是排列。
我知道19683很多,但我之后会根据一些标准来减少数量。
解决方案
以下函数返回一个迭代器,用于生成如OP中所描述的矩阵排列:
function variations(size, vals)
n = prod(size)
k = length(vals)
idxs = CartesianIndices(ntuple(i->k, n))
return Iterators.map(idxs) do x
return reshape(getindex(vals, collect(Tuple(x))), size)
end
end
重要的工作是由 CartesianIndices
完成的,它返回一个遍历张量所有可能的索引的迭代器。稍微调整一下形状就能得到答案。
一个比原文例子小一点的例子是:
julia> variations((2,2),[-5,5]) |> collect |> vec
16-element Vector{Matrix{Int64}}:
[-5 -5; -5 -5]
[5 -5; -5 -5]
[-5 -5; 5 -5]
[5 -5; 5 -5]
[-5 5; -5 -5]
[5 5; -5 -5]
[-5 5; 5 -5]
[5 5; 5 -5]
[-5 -5; -5 5]
[5 -5; -5 5]
[-5 -5; 5 5]
[5 -5; 5 5]
[-5 5; -5 5]
[5 5; -5 5]
[-5 5; 5 5]
[5 5; 5 5]
问题要求以下迭代器:
variations((3,3),[-1, 0, 1])