Performance 朱莉娅:有没有办法用离散集合中的条目来枚举所有大小为m×n的矩阵?
我正在处理一组二维网格中两个变量f(x,y)的函数。网格中每个点的函数本身只能从有限集中获取值。我需要列举我能构造的所有可能的函数 特别是,函数定义为矩阵,其中第i个第j个元素告诉我在x_i,y_j处计算的函数值 我希望能够创建所有可能的矩阵。我知道这样的矩阵的总数是nf^(nx*ny),其中nf是函数在一个点上可以接受的值的数量,nx,ny是x和y的网格中的点的数量。因此,我的测试将使用少量的网格点 多谢各位Performance 朱莉娅:有没有办法用离散集合中的条目来枚举所有大小为m×n的矩阵?,performance,matrix,julia,permutation,Performance,Matrix,Julia,Permutation,我正在处理一组二维网格中两个变量f(x,y)的函数。网格中每个点的函数本身只能从有限集中获取值。我需要列举我能构造的所有可能的函数 特别是,函数定义为矩阵,其中第i个第j个元素告诉我在x_i,y_j处计算的函数值 我希望能够创建所有可能的矩阵。我知道这样的矩阵的总数是nf^(nx*ny),其中nf是函数在一个点上可以接受的值的数量,nx,ny是x和y的网格中的点的数量。因此,我的测试将使用少量的网格点 多谢各位 我试图将问题表示为枚举树中的所有分支并使用递归,但无法创建矩阵作为输出。这是您想要的
我试图将问题表示为枚举树中的所有分支并使用递归,但无法创建矩阵作为输出。这是您想要的吗
function funs(fs)
nf = length(fs)
@assert length(unique(size.(fs))) == 1
nx,ny = size(fs[1])
sigs = Iterators.product(ntuple(i -> 1:nf, nx*ny)...)
([fs[sig[i+(j-1)*nx]][nx,ny] for i in 1:nx, j in 1:ny] for sig in sigs)
end
我返回了一个生成器,您可以轻松地迭代它而不必具体化,因为收集它可能会占用太多内存。当然,对于小数据,您可以收集
它,另外的好处是它将是一个nx*ny
维度数组,允许您轻松地对不同维度进行切片
以下是一个例子:
julia> fs = [fill(1,2,2), fill(2,2,2), fill(3,2,2)]
3-element Array{Array{Int64,2},1}:
[1 1; 1 1]
[2 2; 2 2]
[3 3; 3 3]
julia> funs(fs)
Base.Generator{Base.Iterators.ProductIterator{NTuple{4,UnitRange{Int64}}},getfield(Main, Symbol("##46#49")){Array{Array{Int64,2},1},Int64,Int64}}(getfield(Main, Symbol("##46#49")){Array{Array{Int64,2},1},Int64,Int64}(Array{Int64,2}[[1 1; 1 1], [2 2; 2 2], [3 3; 3 3]], 2, 2), Base.Iterators.ProductIterator{NTuple{4,UnitRange{Int64}}}((1:3, 1:3, 1:3, 1:3)))
julia> collect(funs(fs))
3×3×3×3 Array{Array{Int64,2},4}:
[:, :, 1, 1] =
[1 1; 1 1] [1 1; 2 1] [1 1; 3 1]
[2 1; 1 1] [2 1; 2 1] [2 1; 3 1]
[3 1; 1 1] [3 1; 2 1] [3 1; 3 1]
[:, :, 2, 1] =
[1 2; 1 1] [1 2; 2 1] [1 2; 3 1]
[2 2; 1 1] [2 2; 2 1] [2 2; 3 1]
[3 2; 1 1] [3 2; 2 1] [3 2; 3 1]
[:, :, 3, 1] =
[1 3; 1 1] [1 3; 2 1] [1 3; 3 1]
[2 3; 1 1] [2 3; 2 1] [2 3; 3 1]
[3 3; 1 1] [3 3; 2 1] [3 3; 3 1]
[:, :, 1, 2] =
[1 1; 1 2] [1 1; 2 2] [1 1; 3 2]
[2 1; 1 2] [2 1; 2 2] [2 1; 3 2]
[3 1; 1 2] [3 1; 2 2] [3 1; 3 2]
[:, :, 2, 2] =
[1 2; 1 2] [1 2; 2 2] [1 2; 3 2]
[2 2; 1 2] [2 2; 2 2] [2 2; 3 2]
[3 2; 1 2] [3 2; 2 2] [3 2; 3 2]
[:, :, 3, 2] =
[1 3; 1 2] [1 3; 2 2] [1 3; 3 2]
[2 3; 1 2] [2 3; 2 2] [2 3; 3 2]
[3 3; 1 2] [3 3; 2 2] [3 3; 3 2]
[:, :, 1, 3] =
[1 1; 1 3] [1 1; 2 3] [1 1; 3 3]
[2 1; 1 3] [2 1; 2 3] [2 1; 3 3]
[3 1; 1 3] [3 1; 2 3] [3 1; 3 3]
[:, :, 2, 3] =
[1 2; 1 3] [1 2; 2 3] [1 2; 3 3]
[2 2; 1 3] [2 2; 2 3] [2 2; 3 3]
[3 2; 1 3] [3 2; 2 3] [3 2; 3 3]
[:, :, 3, 3] =
[1 3; 1 3] [1 3; 2 3] [1 3; 3 3]
[2 3; 1 3] [2 3; 2 3] [2 3; 3 3]
[3 3; 1 3] [3 3; 2 3] [3 3; 3 3]
以下是我对OP的理解:
function all_functions(finite_set, nx, ny)
I = Iterators.product(fill(finite_set, nx*ny)...)
(reshape(collect(i), (nx,ny)) for i in I)
end
在行动中:
julia>fs = (0,1,2,3)
julia>collect(Iterators.take(all_functions(fs, 2, 2), 8))
Array{Int64,2}[[0 0; 0 0], [1 0; 0 0], [2 0; 0 0], [3 0; 0 0], [0 0; 1 0], [1 0; 1 0], [2 0; 1 0], [3 0; 1 0]]