Есть ли способ создать пользовательский нормализованный массив NumPy с учетом графа networkx, содержащий узлы и веса в Python - PullRequest
1 голос
/ 30 октября 2019

У меня есть неориентированный и взвешенный граф networkx, в котором 'n' узлов. Я хочу создать симметричную пользовательскую матрицу numpy так, чтобы она имела форму n на n. Я пытаюсь разработать решение, которое не зависит от «имени», данного узлу при его создании.

Каждое ребро имеет заданный вес.

Необходимо применять только три правила:

  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. Следовательно, положение (1,3) и положение (3,1) равны 1 / sqrt (1 * 0,8) = 1 / sqrt (0,8).

Я понимаю, что сеть x имеет встроенныйФункциональность 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 Ответ

1 голос
/ 31 октября 2019

Раствор 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
...