3d 矩阵到 2d 邻接矩阵或边列表

3d matrix to 2d adjacency matrix or edgelist

考虑一个 3 x 3 x 3 立方体,其中 27 个元素中的每一个都沿着面连接到其他元素。立方体元素有 6 个边,因此每个元素最多可以有 6 个连接(例如,3 x 3 x 3 立方体中最中心的元素由 6 个元素包围,并且有 6 个连接)。

那么,设m1m2m3分别为立方体的第一层、第二层、第三层。每个元素的名称是xyz,其中xyz是元素的行号、列号和层号。例如元素213在立方体的第2行第1列第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 欢迎提出解决方案。

我手动创建了二维邻接矩阵,其中的行和列由下面的 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,并且是对称的。它看起来像这样:

这里有一个 dput() 用于 C&P 和验证。

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")))

如果你只想使用来自igraph的包函数:

#adj <- my.adjacency.matrix
as_edgelist(graph.adjacency(adj))

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

plot.igraph(graph.adjacency(adj))

当节点之间的曼哈顿距离为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)