PyG edge index 如何转换回 邻接矩阵?

PyG的edge index形式是$[(node_1,node_2), (node_1, node_3)...]$这种edge pair。
想转换回 邻接矩阵 的形式。

阅读 992
avatarAI BotBETA

当然,从PyG的边索引转换为邻接矩阵是可能的。为了帮助理解这个过程,让我们先了解一下什么是邻接矩阵和边索引。

邻接矩阵是一个二维矩阵,其中行和列都表示图中的节点,而每个元素表示两个节点之间的边的存在或权重。例如,如果节点i与节点j之间存在一条边,邻接矩阵的第i行第j列的元素将是1(对于无权图)或边的权重(对于有权图)。

边索引是一种存储图形结构的方法,其中边作为实体存储,每个边都包含两个节点(即边的端点)。这种方法在处理大规模图形时非常有效。

现在,假设你有一个PyG边的索引列表,并且你希望将其转换为邻接矩阵。以下是一个可能的Python代码片段来实现这一转换:

import torch

# 假设你的边索引是这样的
edge_index = torch.tensor([[0, 1, 2],
                           [1, 0, 3]])

# 计算邻接矩阵
adj_matrix = torch.sparse.FloatTensor(edge_index, torch.ones(edge_index.size(1)), torch.Size([num_nodes, num_nodes])).to(device)

# 将邻接矩阵转换为密集格式
adj_matrix = adj_matrix.to_dense()

请注意,这个代码假设图是无向的(即边是双向的),并且每条边都连接两个不同的节点。此外,你需要知道图中的节点数量(num_nodes)。如果你的图是有向的(即边只能从一个节点到另一个节点),或者每条边连接同一对节点(例如,完全连接的图),那么你可能需要对这个代码进行一些修改。

1 个回答

PyG的edge index形式是$[(node_1,node_2), (node_1, node_3)...]$这种edge pair。

naive

直接for循环,吧edge index里面的位置填充1:

import torch  
  
def edge_index_to_adjacency_matrix(edge_index, num_nodes):  
    # 创建大小为 (num_nodes, num_nodes) 的二维张量  
    adjacency_matrix = torch.zeros(num_nodes, num_nodes)  
      
    # 根据边索引填充邻接矩阵的元素  
    for i, j in zip(*edge_index):  
        adjacency_matrix[i, j] = 1  
        adjacency_matrix[j, i] = 1  
      
    return adjacency_matrix

效率很低

利用传播机制

用PyTorch的广播机制,通过将边索引直接作为索引,一次性将对应的邻接矩阵元素设置为1,避免了使用for循环进行逐个元素的填充。这种方法在大规模图形上具有更高的效率。

import torch  
  
def edge_index_to_adjacency_matrix(edge_index, num_nodes):  
    # 构建一个大小为 (num_nodes, num_nodes) 的零矩阵  
    adjacency_matrix = torch.zeros(num_nodes, num_nodes, dtype=torch.uint8)  
      
    # 使用索引广播机制,一次性将边索引映射到邻接矩阵的相应位置上  
    adjacency_matrix[edge_index[0], edge_index[1]] = 1  
    adjacency_matrix[edge_index[1], edge_index[0]] = 1  
      
    return adjacency_matrix
推荐问题
宣传栏