python - 3d 矩阵到 2d 邻接矩阵或边缘列表
问题描述
考虑一个3 x 3 x 3的立方体,其中 27 个元素中的每一个都沿面连接到其他元素。立方体形状的元素有 6 个边,因此每个元素最多可以有 6 个连接(例如,3 x 3 x 3 立方体中最中心的元素由 6 个元素包围,并且有 6 个连接)。
然后,让m1
、m2
和m3
分别为立方体的第一、第二和第三层。每个元素的名称是xyz
,其中x
,y
,z
是元素的行号、列号和层号。例如,元素213
位于立方体的第二行、第一列和第三层。该元素与其他 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,并且是对称的。它看起来像这样:
这是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")))
解决方案
当节点之间的曼哈顿距离为 1 时有一条边,因此您可以dist()
在 R 中使用来创建邻接矩阵:
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)