【问题标题】:MATLAB function graphallshortestpaths not returning symmetric matrixMATLAB函数graphallshortestpaths不返回对称矩阵
【发布时间】:2017-09-29 05:33:23
【问题描述】:

我正在使用 MATLAB 函数 graphallshortestpaths 来计算无向网络的顶点之间的最短路径。无向网络以加权边列表文件的形式给出,您可以找到here

这是我用来计算最短路径的 MATLAB 代码:

A=load('genome_edge_list');

%Extract the edges
E=[A(:,1);A(:,2)]; 

%Extract the vertices
V=unique(E); 

%N is the number of vertices
N=length(V); 

%Take the inverse of the weights
A(:,3)=1./A(:,3);

%Create a sparse weighted adjacency matrix
B=sparse(A(:,1),A(:,2),A(:,3),N,N);

%Make B symmetric
B=sparse(full(B)+full(B)');

%Compute shortest paths
D=graphallshortestpaths(B,'directed',false);

现在,MATLAB 输出的矩阵 D 不是对称的。但是,由于 graphallshortestpaths 的输入是稀疏格式的对称矩阵,因此输出应该是对称矩阵。那我做错了什么?

我可以在 mathworks 上找到的唯一相关问题是 this 问题,但是在那个问题中,OP 显然没有给出对称矩阵作为输入,这解释了为什么 MATLAB 返回的矩阵不是对称的。

编辑:

为了查看 D 和 D' 的距离,我计算了以下内容:

E=D';
C=D==E;
find(C==0)

这将返回以下线性索引:

 33133
 543038
 1363077
 1398421
 1398786
 1399373

但是这些索引处的 D 和 E 的值是相同的,例如D(33133)=0.1024=E(33133)。现在,如果我取这两个矩阵的差,那么我发现这些索引的差是 -1.0000e-05。因此,正如@beaker 指出的那样,这似乎是一个舍入错误。但是,正如我在下面的评论中所写,我不明白这是怎么发生的,因为 graphsallshortestpaths 只计算节点 i 和 j 之间的距离一次,所以 D(i,j) 和 D(i,j) 的值应该是相同计算的结果。

【问题讨论】:

  • 数值相差多远?我唯一能想到的就是浮点精度。另外,我认为第三行应该是V=unique(E);,因为H 是未定义的,但即使H 已经在其他地方定义,我也看不出这会如何导致问题。
  • @beaker 谢谢,这是一个错字。我检查了C=D==D.'find(C==0) 的值偏离了多远,给了我一个包含 D 和 D 的六个索引的列表。应该不同。但是,这些索引的值是相同的,所以我对为什么 issymmetric(D) 返回 0 感到困惑。
  • 一个小例子会有所帮助。
  • @beaker,我通过计算两个矩阵的差异再次检查,在这六个索引处,它们的差异为 -1.0000e-05。所以这似乎是一个四舍五入的问题。但是,我看不到它发生在哪里,因为节点 i 和节点 j 之间的距离应该只由 graphsallshortestpaths 计算一次,因此 D(j,i) 的值应该与 D(i, j).
  • @beaker 我将在问题中添加一个示例。

标签: matlab shortest-path adjacency-matrix


【解决方案1】:

情侣或备注:

  • 正如@beaker 在评论中提到的,这很可能是一个数字问题。我会特别厌倦您采取逆向并执行A(:,3)=1./A(:,3); 的行。尝试输出一些调试值,看看这个逆向是否符合您的预期。
  • 在您创建B 对称的行上:您确定要创建full(b)' 而不是full(b).'?第一个采用 Hermitian,第二个采用转置!
  • 同样在您使B 对称的同一行上:也许您在其中缺少0.5 因素?因此,不要使用 B=sparse(full(B)+full(B)'); 之类的 B=sparse((full(B)+full(B).').*0.5);(参见 this answer)。

我也认为你无意中在第二行写了H而不是E,对吧?

【讨论】:

  • 感谢您的评论。即使我不采用权重的倒数 issymmetric(D) 仍然返回 0,而 A(:,3)=1./A(:,3) 行实际上做了我想要它做的事情。至于你的第二句话,因为我处理的是实数,所以无论我是采用厄米特还是转置都没有区别。
  • 最后,由于我有一个无向图的加权边列表,列表中没有重复边,将矩阵的转置添加到自身是获得加权对称邻接的正确方法矩阵,因为我不会复制任何值,而使用 (full(B)+full(B).')*05 我会将所有权重分成两半,这不是我想要做的。
猜你喜欢
  • 2012-11-03
  • 1970-01-01
  • 1970-01-01
  • 2021-05-11
  • 1970-01-01
  • 2015-03-23
  • 1970-01-01
  • 1970-01-01
  • 2021-03-06
相关资源
最近更新 更多