【问题标题】:Cost-effective creation of a symmetric matrix in MATLAB在 MATLAB 中经济高效地创建对称矩阵
【发布时间】:2013-04-16 03:46:56
【问题描述】:

我对 MATLAB 相当陌生,并且有一段代码可以创建距离矩阵。更准确地说,它在无向图上的点之间创建距离矩阵 D,使得 Dij 是该图上点之间的最短路径。这个矩阵显然是对称的(因为图是无向的),下面是我用来创建它的代码 sn-p:

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

这显然非常浪费,因为我没有利用矩阵的对称性。有什么方法可以只计算矩阵的上三角部分,然后以某种方式将下三角部分“附加”到它,这样我就可以将计算从 n^2 减少到 n^2 / 2?

任何帮助表示赞赏,

杰森

【问题讨论】:

    标签: matlab matrix


    【解决方案1】:

    当然。想想迭代的顺序,找出最先到达的三角形。

    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 j >= i

    【讨论】:

    • 我会选择这个,因为我发现它是最简单的方法,唯一的开销是参考副本。谢谢。
    【解决方案2】:

    对于无向和无权图,计算距离矩阵的另一种方法

    如果您想减少运行时间,可能会有所帮助。在 Matlab 的情况下,大多数时候,我发现逐个扫描条目比较慢。我只是猜测你问这个问题的目的,如果我跑题了,对不起。

    给定一个邻接矩阵 ( G ),我将按以下方式计算距离矩阵,

    假设: 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) 在“G power k”中的条目会给你步行的次数 G中从Vi到Vj的长度k
    • 最后connect会告诉你图是否连通

    【讨论】:

    • @yuk:我可以看看你的测试用例吗?此方法仅适用于无向和无权图。这两个假设将保证 G 是对称的并且只填充了“0”和“1”。这是一种特殊情况。
    • 收回我的评论。您的代码结果对于对称矩阵是对称的。它与 graphshortestpath 的风格不同,带有 1s 和 Infs 的边缘没有连接。这确实是最快的方法。 +1
    【解决方案3】:

    您可以为矩阵G 的下部生成索引

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

    然后你可以遍历这些索引:

    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';
    

    另一种选择是使用带有这些索引的 ARRAYFUN 和 SQUAREFORM 将结果向量转换为方阵:

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

    【讨论】:

    • 这看起来不像是有效的语法。
    • @yuk 你在计算对角线元素吗?
    • @jucestain: 处理距离时,对角线元素都应该为零。
    • 没有。如果是无向图,我认为它们不会高于 0。@Jason,我说得对吗?
    • @yuk:我认为您正在计算find 返回的行和列的笛卡尔积。您想改为迭代成对列表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-23
    • 1970-01-01
    相关资源
    最近更新 更多