直接创建稀疏邻接矩阵 - (矩阵超过最大数组大小首选项)

时间:2016-06-22 13:03:44

标签: matlab memory

问题

我在我的算法中使用了一个邻接矩阵,只要我测试了一个小矩阵(3000)点就可以正常工作。但我的实际问题包括167620点,我想为该问题创建一个邻接矩阵。 但显然由于长度我得到以下问题:

Requested 167620x167620 (209.3GB) array exceeds maximum array size preference. Creation of arrays greater than this limit may take a
long time and cause MATLAB to become unresponsive.

我使用以下代码:

adjMat = zeros(size(NB_list_all,1));                      
for ind = 1:size(NB_list_all,1)
        adjMat(ind, nonzeros(NB_list_all(ind,2:end))) = 1; 
end
adjMatS=sparse(adjMat);                                    
G=digraph(adjMatS);                                        
E=table2array(G.Edges);                                    

如你所见,我基本上需要边缘列表。

问题

因此问题:有没有办法直接计算稀疏邻接矩阵,还是有一种不同的方法从邻接列表中获取边缘列表? 我的NB_list_all包含第1列中的点和第2-5列中的邻居?

修改

我的NB_list_all是以下形式的附带列表:

1   2   0
2   3   1
3   4   2
4   5   3
5   6   4
6   7   5
7   8   6
8   9   7
9   0   8

第一列是点,而第2列:第5列是与它相邻的点的位置。如果没有邻居则为0。我想要创建边缘列表的矩阵是167620x5。我在使用matlab的E=table2array(G.Edges);图形函数之前创建了边缘列表。现在我基本上有两个问题:

  1. 如何直接从此邻接列表创建稀疏邻接矩阵?

  2. 是否有更简单的方法为这种邻接列表创建边缘列表? 非常感谢!

1 个答案:

答案 0 :(得分:3)

如果您知道所有索引和值以及矩阵的结束大小,则可以使用

创建稀疏矩阵
adjMat = sparse(indexi,indexj,value,size1,size2);

一气呵成。实际上,这是创建稀疏矩阵的优先方式。

示例:

您需要以下矩阵:

  0 1 1
  1 0 0
  0 0 1

你会把它建成:

sparse([1 1 2 3], [2 3 1 3],[1 1 1 1],3,3)

以你给出的例子:

NB_list_all=[
1   2   0
2   3   1
3   4   2
4   5   3
5   6   4
6   7   5
7   8   6
8   9   7
9   0   8];


% if the first index contains all numbers we can safely do this
% this is almost indexJ, but we have some zeroes that we dont like
indexJ=NB_list_all(:,2:end); 

% create indexI
indexI=repmat(1:size(indexJ,1),size(indexJ,2),1).';

% lets unroll the matrices
indexI=indexI(:);
indexJ=indexJ(:);
% lets remove the indexI and NB_list_all that have a zero somewhere, because those are not real
notzero=find(indexJ);
indexI=indexI(notzero);
indexJ=indexJ(notzero);

adjMat=sparse(indexI,indexJ,1,size(NB_list_all,1),size(NB_list_all,1));