Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中,如果networkx图形包含节点和权重,有没有办法创建自定义的标准化numpy数组_Python_Numpy_Networkx_Graph Theory - Fatal编程技术网

在python中,如果networkx图形包含节点和权重,有没有办法创建自定义的标准化numpy数组

在python中,如果networkx图形包含节点和权重,有没有办法创建自定义的标准化numpy数组,python,numpy,networkx,graph-theory,Python,Numpy,Networkx,Graph Theory,我有一个networkx无向加权图,它有n个节点。我想创建一个对称的自定义numpy矩阵,使其具有n×n的形状。我正在尝试设计一个解决方案,它不依赖于创建节点时给定的“名称” 每条边都有一个给定的权重 只有三条规则需要适用: 矩阵的对角线必须等于1 如果图形中的两个节点未连接,则数组中的该位置将填充0。对于eg,如果节点1和节点2未连接,则位置(1,2)和位置(2,1)等于0 如果两个节点连接。对于每个节点,我需要计算与该节点关联的所有边的权重之和,然后应用1/sqrt(w_1*w_2)。对于e

我有一个networkx无向加权图,它有n个节点。我想创建一个对称的自定义numpy矩阵,使其具有n×n的形状。我正在尝试设计一个解决方案,它不依赖于创建节点时给定的“名称”

每条边都有一个给定的权重

只有三条规则需要适用:

  • 矩阵的对角线必须等于1
  • 如果图形中的两个节点未连接,则数组中的该位置将填充0。对于eg,如果节点1和节点2未连接,则位置(1,2)和位置(2,1)等于0
  • 如果两个节点连接。对于每个节点,我需要计算与该节点关联的所有边的权重之和,然后应用
    1/sqrt(w_1*w_2)
    。对于eg,如果节点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)
  • 我确实意识到networkx有一个内置的标准化拉普拉斯矩阵功能,但据我所知,它并没有构建我想要的功能

    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 解决方案2
    我认为输出值不正确。然而,在编译之后,我意识到当图形有许多节点(1000)时,由于嵌套for循环的性质,它可能需要很长时间。由于应用程序是时间敏感的,有没有其他方法可以做到这一点,不必使用numpy如果你想要速度,你必须依赖numpy。我会修正结果,但循环可能无法避免。你还想要有循环的解决方案吗?如果可以设计一个没有循环的解决方案,那就太好了!但如果不是这样,那么只要输出正确,循环就可以工作。谢谢我已经用矩阵为你解决了这一切!好好享受吧。在第三个条件示例中,您说“节点1可以连接到图中的其他两个节点”,这应该是非常明确的。这包括节点3吗?换句话说,节点1的度数是2还是3?抱歉,我知道你是从哪里来的。它的度数为2。其中一条已建立的边介于1和3之间。好的,谢谢。还有一个问题。在您的示例中,据我所知,A的总重量为0.125+0.75=0.875,B的总重量为0.125+1.2=1.325,因此边A-B的重量应为1/sqrt(1.325*0.875)=1/sqrt(1.159375)=1/1.0767427733679016=0.928726920425144。不是1/sqrt(2.2)。2.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))
    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.        ]])
    
    
    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