给定一个包含 python 中的节点和权重的 networkx 图,有没有一种方法可以创建自定义规范化 numpy 数组

Is there a way to create custom normalised numpy array given a networkx graph containing nodes and weights in python

我有一个 networkx 无向加权图,其中有 'n' 个节点。我想创建一个对称的自定义 numpy 矩阵,使其形状为 n x n。我正在尝试设计一个解决方案,该解决方案不依赖于创建时提供给节点的 'name'。

每条边都有给定的权重。

只需要应用三个规则:

  1. 矩阵的对角线需要等于 1。
  2. 如果图中的两个节点未连接,则数组中的那个位置填充为 0。例如,如果节点 1 和节点 2 未连接,则位置 (1,2) 和位置 (2,1)等于 0。
  3. 如果两个节点相连。对于每个节点,我需要计算与该节点关联的所有边的权重总和,然后应用 1/sqrt(w_1*w_2)。例如,如果节点 1 和 3 已连接。节点 1 可以连接到图中的 2 个节点,这两个连接的边权重分别为 0.6 和 0.4,因此 w_1=0.6+0.4。节点3可以连接图中的3个节点,其中边权重分别为0.5、0.2、0.1,w_2=0.5+0.2+0.1。因此 position(1,3) 和 position(3,1) 等于 1/sqrt(1*0.8) = 1/sqrt(0.8).

我知道 networkx 有一个内置的 normalized_laplacian_matrix 功能,但据我所知,它并没有构建我正在寻找的东西。

Example:
    FG=nx.Graph()
    FG.add_weighted_edges_from([('A','B',0.125),('A','C',0.75),('B','D',1.2),('C','D',0.375)])

因此这应该产生以下矩阵

   ([[1.        , 0.92872692, 1.00790526, 0.        ],
    [0.92872692, 1.        , 0.        , 0.69223218],
    [1.00790526, 0.        , 1.        , 0.75124823],
    [0.        , 0.69223218, 0.75124823, 1.        ]])    

解决方案 1

import networkx as nx
FG=nx.Graph()
FG.add_weighted_edges_from([('A','B',0.125),('A','C',0.75),('B','D',1.2),('C','D',0.375)])

length = len(FG.nodes())
matrix = nx.convert_matrix.to_numpy_matrix(FG)
new_matrix = np.zeros((length,length))
new_matrix = 1/np.sqrt(matrix.sum(axis=1)*matrix.sum(axis=0))
new_matrix[matrix==0] = 0
np.fill_diagonal(new_matrix,1)


new_matrix
matrix([[1.        , 0.92872692, 1.00790526, 0.        ],
        [0.92872692, 1.        , 0.        , 0.69223218],
        [1.00790526, 0.        , 1.        , 0.75124823],
        [0.        , 0.69223218, 0.75124823, 1.        ]])

解决方案 2

import networkx as nx
FG=nx.Graph()
FG.add_weighted_edges_from([('A','B',0.125),('A','C',0.75),('B','D',1.2),('C','D',0.375)])

length = len(FG.nodes())
matrix = nx.convert_matrix.to_numpy_matrix(FG)
new_matrix = np.zeros((length,length))

import numpy as np
for i in range(length):
    for j in range(length):
        if i == j:
            new_matrix[i,j] = 1
        elif matrix[i,j] == 0:
            new_matrix[i,j] = 0
        else:
            w_1 = matrix[:,i].sum()
            w_2 = matrix[j,:].sum()
            new_matrix[i,j] = 1/np.sqrt(w_1*w_2)
new_matrix