朱莉娅稀疏矩阵随机1的

时间:2018-01-13 11:43:19

标签: random julia sparse-matrix

所以我在julia中有一个N大小,我需要一个NxN稀疏矩阵,其中有N个,在随机的地方。什么是最好的方法呢?

首先,我考虑随机生成索引,然后在稀疏矩阵中将这些数字设置为1,但我最近发现了spnd函数但是我不明白如何正确使用它们或将它们应用于我的问题。我尝试使用它有限的理解,它不断产生错误信息。当然,我们非常感谢帮助。)

3 个答案:

答案 0 :(得分:2)

受上述@DanGetz评论的启发,以下解决方案是使用randperm的单行函数。我删除了原来的答案,因为它不是很有帮助。

sparseN(N) = sparse(randperm(N), randperm(N), ones(N), N, N)

这也非常快:

@time sparseN(10_000);
  0.000558 seconds (30 allocations: 782.563 KiB)

答案 1 :(得分:1)

维度(N行)x(M列)的稀疏矩阵具有至多NxM个分量,可以使用K = [0,N * M]整数集来索引。对于K中的任何k,您可以检索元素索引(i,j),这要归功于欧几里德除法k = i + j * N(此处为列主要布局)。

要随机抽样K个元素(重复),您可以在其书Vol2., seminumerical-Algorithms中使用Knuth算法“算法S(选择抽样技术)”3.4.2 p>

朱莉娅:

function random_select(n::Int64,K::Int64) 
    @assert 0<=n<=K

    sample=Vector{Int64}(n)
    t=Int64(0)
    m=Int64(0)

    while m<n
        if (K-t)*rand()>=n-m
            t+=1
        else
            m+=1
            sample[m]=t
            t+=1
        end
    end
    sample
end

下一部分只是检索I,J索引,从其坐标形式创建稀疏矩阵:

function create_sparseMatrix(n::Int64,N::Int64,M::Int64)
    @assert (0<=N)&&(0<=M)
    @assert 0<=n<=N*M

    nonZero = random_select(n,N*M)

    # column major: k=i+j*N
    I = map(k->mod(k,N),nonZero)
    J = map(k->div(k,N),nonZero)

    sparse(I+1,J+1,ones(n),N,M)
end

用法示例:一个4x5稀疏矩阵,随机位置有3个非零(= 1.0):

julia> create_sparseMatrix(3,4,5)
4×5 SparseMatrixCSC{Float64,Int64} with 3 stored entries:
  [4, 1]  =  1.0
  [3, 2]  =  1.0
  [3, 3]  =  1.0

边境案例测试:

julia> create_sparseMatrix(0,4,5)
4×5 SparseMatrixCSC{Float64,Int64} with 0 stored entries

julia> create_sparseMatrix(4*5,4,5)
4×5 SparseMatrixCSC{Float64,Int64} with 20 stored entries:
  [1, 1]  =  1.0
  [2, 1]  =  1.0
  [3, 1]  =  1.0
  [4, 1]  =  1.0
  ⋮
  [4, 4]  =  1.0
  [1, 5]  =  1.0
  [2, 5]  =  1.0
  [3, 5]  =  1.0
  [4, 5]  =  1.0

答案 2 :(得分:1)

坚持一线解决方案:

using StatsBase
sparseones(N,M,K) = sparse(
  (x->(first.(x).+1,last.(x).+1))(divrem.(sample(0:N*M-1,K,replace=false),M))...,
  ones(K),N,M
)

,并提供:

julia> sparseones(3,4,5)
3×4 SparseMatrixCSC{Float64,Int64} with 5 stored entries:
  [1, 1]  =  1.0
  [2, 1]  =  1.0
  [3, 3]  =  1.0
  [2, 4]  =  1.0
  [3, 4]  =  1.0

此方法与早期答案基本相同,具有重用现有sample并且更短的优势。在较大的矩阵上它甚至更快。