3D矩阵转换为2D邻接矩阵或边列表

3
考虑一个3 x 3 x 3的立方体,其中每个27个元素都与其他元素沿面连接。立方体形状的元素有6个面,因此每个元素最多可以有6个连接(例如,在3 x 3 x 3立方体中间最核心的元素被6个元素包围,并且具有6个连接)。
然后,让m1m2m3分别成为立方体的第一层、第二层和第三层。每个元素的名称是xyz,其中xyz是元素的行编号,列编号和层编号。例如,元素213位于立方体的第二行,第一列和第3层。此元素连接到4个其他元素:其中三个在它的层中(113, 313, 223),另一个在它上面一层(212)。
x = 3 # nrow
y = 3 # ncol
z = 3 # nlay

# print each layer as a 2D matrix
for(k in 1:z){
  m = paste0(rep(1:x, each=x), rep(1:y, times = y), k)
  print(matrix(m, nrow=x, byrow=T))
}

     [,1]  [,2]  [,3] 
[1,] "111" "121" "131"
[2,] "211" "221" "231"
[3,] "311" "321" "331"
     [,1]  [,2]  [,3] 
[1,] "112" "122" "132"
[2,] "212" "222" "232"
[3,] "312" "322" "332"
     [,1]  [,2]  [,3] 
[1,] "113" "123" "133"
[2,] "213" "223" "233"
[3,] "313" "323" "333"

是否有一个 igraph 或相关包中的开箱即用函数,可以创建像这样的网络的邻接矩阵或边缘列表?我需要一个可适用于任意行、列和层数的解决方案。欢迎使用Python解决方案。

我手动创建了2D邻接矩阵,其中行和列由下面的c(m1, m2, m3)给出:

m1 = paste0(rep(1:x, each=x), rep(1:y, times = y), 1)
m2 = paste0(rep(1:x, each=x), rep(1:y, times = y), 2)
m3 = paste0(rep(1:x, each=x), rep(1:y, times = y), 3)
c(m1, m2, m3)
 [1] "111" "121" "131" "211" "221" "231" "311" "321" "331" "112" "122" "132" "212" "222" "232" "312" "322" "332"
[19] "113" "123" "133" "213" "223" "233" "313" "323" "333"

对于这个简单的例子,邻接矩阵是稀疏的,对角线上是0,并且对称。它看起来像这样:

enter image description here

这里有一个 dput() 的代码可直接复制粘贴并验证。

dput(temp)
structure(c(0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 
1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 
1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 
1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 
0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 
1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 
0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 
0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 
0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0), .Dim = c(27L, 
27L), .Dimnames = list(c("111", "121", "131", "211", "221", "231", 
"311", "321", "331", "112", "122", "132", "212", "222", "232", 
"312", "322", "332", "113", "123", "133", "213", "223", "233", 
"313", "323", "333"), c("111", "121", "131", "211", "221", "231", 
"311", "321", "331", "112", "122", "132", "212", "222", "232", 
"312", "322", "332", "113", "123", "133", "213", "223", "233", 
"313", "323", "333")))
2个回答

3

当节点之间的曼哈顿距离为1时,存在边缘关系。因此,您可以使用R中的dist()函数来创建邻接矩阵:

cube_mat = expand.grid(
    x = 1:3,
    y = 1:3,
    z = 1:3
)

m_dist = as.matrix(dist(cube_mat[, 1:3], method = "manhattan", diag = TRUE))
# Zero out any distances != 1
m_dist[m_dist != 1] = 0
rownames(m_dist) = paste0(cube_mat$x, cube_mat$y, cube_mat$z)
colnames(m_dist) = paste0(cube_mat$x, cube_mat$y, cube_mat$z)
# Plot of the adjacency matrix (looks reversed because 111 is in the bottom left):
image(m_dist)

1
如果您只想使用来自igraph的软件包函数:
#adj <- my.adjacency.matrix
as_edgelist(graph.adjacency(adj))

通常情况下,您可以使用igraph包中的函数在边缘列表、邻接矩阵之间进行转换,并使用plot.igraph生成图形。这是默认的立方体:

plot.igraph(graph.adjacency(adj))

default network plot


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接