python 网络X边介数中心性函数不考虑权重

edqdpe6u  于 2022-11-28  发布在  Python
关注(0)|答案(1)|浏览(218)

我试图随机化一个网络x图的链接权重来改变网络的介数中心性。我已经验证了权重确实改变了,但它并没有改变edge_betweeness_centrality函数的输出。我怀疑这与向节点和边添加对象有关,因为只要我没有这些就能让它工作。然而,我的代码的其他部分需要这些对象,因此不能删除它们。
我试过load_centrality和betweenness_centrality,都给予了同样的问题。我还验证了我的输入是整数还是浮点数。我知道函数会将值解释为距离,所以我试过普通权重和权重的倒数。我已经在这个问题上纠结了好几周了,希望能得到任何帮助或想法。谢谢。
下面是我的代码。

import networkx as nx
import numpy as np 
from itertools import combinations, groupby
import random 

class Link(object):
  def __init__(self,link_id,rate,distance,network):
        self.link_id = link_id 
        self.rate = rate
        self.distance = distance
        self.network = network
        self.buffer = [] 

class Node:
    def __init__(self,node_id,network): 
        self.node_id = node_id
        self.len = 0   
        self.queue = []
        self.network = network
        self.packet_delay = []
        self.packets = []

def gnp_random_connected_graph(n, p):
        graph_seed = np.random.default_rng(2021)

        network = nx.Graph()
        
        node_dict = {}
        for node in range(n):
            new_node = Node(node, network)
            node_dict[node] = new_node
            

        network.add_nodes_from(node_dict.items())

        edges = list(combinations(range(n), 2))
        link_dict = {}
        for id, node_edges in groupby(edges, key=lambda x: x[0]): 
            rate = random.randint(8000000,40000000) #bps
            distance = random.randint(10,185) #meters
            node_edges = list(node_edges) 
            random_edge = tuple(graph_seed.choice(node_edges))
            link_dict[random_edge] = Link(random_edge,rate,distance,network)
        
        for e in node_edges:  
            if graph_seed.random() < p: 
                link_dict[e] = Link(e,rate,distance,network)

        for key,value in link_dict.items(): 
            nodes = list(network.nodes)
            network.add_edge(nodes[key[0]],nodes[key[1]],obj=value,weight=int(value.distance),rp = float(1/(value.distance)))
            
        return network        

def randomize_weights(network):

            for edge in network.edges():
                rand_num = random.randint(10,100) 
                network[edge[0]][edge[1]]['weight'] = rand_num
                network[edge[0]][edge[1]]['rp'] = 1/rand_num

            return network  

org_net = gnp_random_connected_graph(10,.1)
#print("edges weight",nx.get_edge_attributes(org_net,'weight'))
bc_dict = nx.edge_betweenness_centrality(org_net, weight='rp')
print("OLD",bc_dict)
new_net = randomize_weights(org_net.copy())
#print("edges weight",nx.get_edge_attributes(new_net,'weight'))
new_bc_dict = nx.edge_betweenness_centrality(new_net, weight='rp')
print("NEW", new_bc_dict)
a64a0gku

a64a0gku1#

一般来说,我对网络算法相对缺乏经验,所以请对我的答案和术语持保留态度。
首先,我认为您的代码确实可以工作。例如,尝试将org_net重新定义为:

org_net = nx.random_geometric_graph(10, 3, seed=42)

这确实会为边产生不同的介数中心性值。从我对介数中心性定义的理解来看,我认为你的问题在于你所选择的图的结构实际上意味着你的边的介数中心性值基本上与权重无关。所以随机化权重会产生相同的值。介数中心性只取决于最短路径的数量,如果你画出你的网络示例,我想你会发现随机化权重并不会影响你的结果:

org_net = gnp_random_connected_graph(10,.1)
pos = nx.spring_layout(org_net, seed=42)
nx.draw(org_net)

给出

另一个可能会妨碍您进行故障排除的潜在冲突问题是networkx(不幸的是,这是经常发生的情况)默默地忽略了一个可能会引发错误的问题。

bc_dict = nx.edge_betweenness_centrality(org_net,weight='banana')

尽管没有边缘属性'banana',但这不会引发错误。

相关问题