所以我在julia中有一个N大小,我需要一个NxN稀疏矩阵,其中有N个,在随机的地方。什么是最好的方法呢?
首先,我考虑随机生成索引,然后在稀疏矩阵中将这些数字设置为1,但我最近发现了spnd函数但是我不明白如何正确使用它们或将它们应用于我的问题。我尝试使用它有限的理解,它不断产生错误信息。当然,我们非常感谢帮助。)
答案 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
并且更短的优势。在较大的矩阵上它甚至更快。