【问题标题】:Create coordinate array from adjacency matrix - Matlab从邻接矩阵创建坐标数组 - Matlab
【发布时间】:2014-07-16 22:14:49
【问题描述】:

我有一个快速的图论问题。

我在 Matlab 中有一个 13 x 13 的邻接矩阵。我已经只取了下对角线(这是一个无向图)并从单位矩阵中减去(因此没有将节点连接到自身的边)。然后,我在左侧添加一列,在顶部添加一行,其中包含四个节点的 ID 号。生成的 14 x 14 邻接矩阵如下所示:

A = 

    0   1   1   1   1   2   2   2   3   3   3   4   4   4
    1   0   0   0   0   0   0   0   0   0   0   0   0   0
    1   0   0   0   0   0   0   0   0   0   0   0   0   0
    1   0   0   0   0   0   0   0   0   0   0   0   0   0
    1   0   0   0   0   0   0   0   0   0   0   0   0   0
    2   1   0   0   0   0   0   0   0   0   0   0   0   0
    2   0   0   0   0   0   0   0   0   0   0   0   0   0
    2   0   0   0   0   0   0   0   0   0   0   0   0   0
    3   0   0   1   0   0   0   0   0   0   0   0   0   0
    3   0   0   0   0   0   0   0   0   0   0   0   0   0
    3   0   1   0   0   0   0   0   0   0   0   0   0   0
    4   1   0   0   0   1   0   0   0   0   0   0   0   0
    4   0   0   0   1   0   0   0   0   0   0   0   0   0
    4   0   0   0   0   0   0   1   0   0   0   0   0   0

如何从中创建坐标数组?我知道结果应该有 7 行(每个唯一节点对一个)。

如果您能提供帮助,请告诉我。提前致谢!

【问题讨论】:

  • 您能否重新格式化该矩阵A?我无法从中做出正面或反面
  • 哈哈,没错,我打字的时候看起来不错——现在想弄清楚。
  • 尝试将每行缩进 4 个空格。这会将其放置在代码块中。
  • 让我快速复习一下邻接矩阵。条目(i,j) 中的数字代表什么?我的理解是这应该只有0和1,它代表节点i,所有其他节点j连接到i
  • 打败我,再次感谢!条目 (i,j) 表示在第一列的第 i 个节点和第一行的第 j 个节点之间存在一条边。所以 (6,2) 处的“1”表示节点 2(见第一列)和节点 1(见第一行)之间有一条边。不过,您是对的,无向图的典型邻接矩阵是 1 和 0 的 13x13 下对角线——我在第一行和第一列中添加了 ID 号,因为这些是我最终需要作为坐标对列出的内容。

标签: matlab coordinates graph-theory adjacency-matrix


【解决方案1】:

我们可以使用在第一行和第一列提供的节点 ID 来帮助我们创建节点邻接列表。我们需要做的是拆分变量,以便我们分离出第一行,称为rowList 和第一列colList。我们将分别表示这些行列表和列列表。我们还将提取邻接矩阵,它是矩阵的其余部分。基本算法如下:

  1. 找出邻接矩阵中非零的行和列。
  2. 使用这些行和列来索引相应的行和列列表,并吐出一个坐标数组。

事不宜迟:

rowList = A(2:end,1);
colList = A(1,2:end).';
AdjMatr = A(2:end,2:end);
[nonZeroRows, nonZeroCols] = find(AdjMatr);
nodeList = [rowList(nonZeroRows) colList(nonZeroCols)];

输出结果如下:

nodeList =

 2     1
 4     1
 3     1
 3     1
 4     1
 4     2
 4     2

这个答案当然不会给出唯一的行,并且会产生重复。如果您希望拥有唯一的行,请考虑这样做:

nodeListUnique = unique(nodeList, 'rows');

输出是:

nodeListUnique =

 2     1
 3     1
 4     1
 4     2

【讨论】:

  • 完成。谢谢你的建议@LuisMendo :)
  • 感谢@LuisMendo 和 rayryeng!我非常感谢您的帮助和快速响应。非常感谢!
  • @DanMcK - 不客气,欢迎来到 StackOverflow!公平地说,Luis Mendo 首先以大约 3 分钟的优势击败了我。感谢您无论如何接受我的回答:)
  • 另外,对于可能觉得这很有用的未来用户,在图论上下文中,这些可能不是传统意义上的“重复”行,而是连接两个节点的多条边——例如,假设节点是棒球队,边缘是为两支球队效力的球员。多名球员在职业生涯中为同一对球队效力是完全可能的。通过仅取邻接矩阵的下对角线来删除相同边缘的“重复”观察。再次感谢大家的帮助。
  • @DanMcK - 酷 :) 这是有道理的(我知道这一点)。作为奖励,如果您想计算节点 ij 之间连接的边数,您可以这样做:counts = accumarray(nodeList, 1);。每个数字将告诉您有多少条边连接到由行索引的第一个节点和由列索引的第二个节点。因此,在counts(4,1),您会看到 this 等于 2,这告诉您在节点 4 和 1 之间连接了 2 条边。
【解决方案2】:

看来你想要的是:

[ii, jj] = find(A(2:end,2:end)); %// row and col indices of ones in inner matrix
result = [ A(ii+1,1) A(1,jj+1).' ]; %'// node numbers corresponding to ii and jj

在你的例子中,这给出了

result =
     2     1
     4     1
     3     1
     3     1
     4     1
     4     2
     4     2

如果您需要唯一的行:

result = unique(result, 'rows');

给了

result =

     2     1
     3     1
     4     1
     4     2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多