简体   繁体   English

在MATLAB中经济高效地创建对称矩阵

[英]Cost-effective creation of a symmetric matrix in MATLAB

I'm fairly new to MATLAB and have a piece of code which creates a distance matrix. 我对MATLAB很新,并且有一段代码可以创建一个距离矩阵。 To be more precise, it creates a distance matrix D between points that lie on an undirected graph, such that Dij is the shortest path between the points on that graph. 更确切地说,它在位于无向图上的点之间创建距离矩阵D,使得Dij是该图上的点之间的最短路径。 This matrix is obviously symmetric (because the graph is undirected) and the following is the code snippet that I use to create it: 这个矩阵显然是对称的(因为图是无向的),以下是我用来创建它的代码片段:

D = zeros(size(data,1));
for i = 1:size(data, 1)
    for j = 1:size(data, 1)
        [D(i, j), ~, ~] = graphshortestpath(G, i, j, 'Directed', false);
    end
end

This is obviously very wasteful, since I'm not exploiting the symmetry of the matrix. 这显然非常浪费,因为我没有利用矩阵的对称性。 Is there any way in which I can compute only the upper triangular part of the matrix and then somehow "append" the lower triangular part to it, such that I reduce my computations from n^2 to n^2 / 2? 有什么方法我只能计算矩阵的上三角形部分然后以某种方式将下三角形部分“追加”到它,这样我就可以将计算从n ^ 2减少到n ^ 2/2?

Any help appreciated, 任何帮助,赞赏,

Jason 贾森

Sure. 当然。 Just think about the order of iteration, to figure out which triangle is reached first. 只需考虑迭代的顺序,找出首先达到的三角形。

D = zeros(size(data,1));
for i = 1:size(data, 1)
    for j = 1:size(data, 1)
        if j > i
            [D(i, j), ~, ~] = graphshortestpath(G, i, j, 'Directed', false);
        else
            D(i, j) = D(j, i);
        end
    end
end

If diagonal elements aren't identically zero, you can use if j >= i instead. 如果对角线元素不是相同的零,则可以使用if j >= i

For undirected and unweighted graph, an alternative way of computing Distance matrix 对于无向和未加权的图形,计算距离矩阵的另一种方法

May help if u are trying to reduce your runtime. 如果您试图减少运行时间,可能会有所帮助。 In the case of Matlab, most of the time, I find scanning entry by entry is slower. 在Matlab的情况下,大多数时候,我发现按入口扫描输入速度较慢。 I am just guessing your purpose of asking the question, sorry if I am out of topic. 我只是猜测你问这个问题的目的,对不起,如果我不在话题。

Given a Adjacency Matix ( G ), I would compute the distance matrix in following way, 给定邻接Matix(G),我会按以下方式计算距离矩阵,

Assumptions: 1. G is undirected & unweighted ( matrix filled with '0' and '1' ) 2. N is the order of the graph with G is of size N x N 假设:1。G是无向和未加权的(矩阵填充'0'和'1')2。N是图的顺序,G的大小为N x N

function [D,connect]=genDistance(G,N)

D = G;
B = G;
connect = 0;
i=1;
while((~connect)&&(i<N-1))    % the maximum distance from one vert to another
    i = i + 1;                % is N-1
    B = B * G;                % G to the power of i
    D = D + i * (D==0&B>0);   % D==0 & B>0 the entries to be updated 
    connect = ( min(min(D)) )>0;  %check if D has zero entry
end
D ( eye(N) ) = 0 ; %clear diagonal entries
  • (i,j) entry in "G power k" will give you the number of walks of length k from Vi to Vj in G (i,j)“G power k”中的条目将给出从G到Vi的长度k的步数k
  • in the end, connect will tell you whether the graph is connected 最后,connect将告诉您图表是否已连接

You can generate indices for the lower part of the matrix G with 您可以为矩阵G的下半部分生成索引

N = length(G);
[irow, icol] = find(tril(ones(N),-1));

Then you can loop through those indices: 然后你可以遍历这些索引:

D = zeros(size(G));
for i = 1:numel(irow)
   [D(irow(i), icol(i)] = graphshortestpath(G, irow(i), icol(i), 'Directed', false);
end
D = D + D';

Another option is to use ARRAYFUN with those indices and SQUAREFORM to convert the resulted vector into a square matrix: 另一个选择是使用带有索引的ARRAYFUN和SQUAREFORM将结果向量转换为方形矩阵:

D = arrayfun(@(x,y) graphshortestpath(G,x,y, 'Directed', false), irow, icol);
D = squareform(D);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM