简体   繁体   中英

Network X: Taking into consideration weight of nodes in network metrics such as betweenness centrality

I recently started using network X and have the following problem.

I have a weighted graph:

  • The nodes have different sizes as they represent the number of people working in an office.
  • The offices are interlinked with weighted edges, which represent the distance between the offices (how long it takes to get from one department to the other one).

I would like to know, in which office (which noded) to put the photocopier. In order to do so, I would like to use network metrics of the betweenness centrality and the closeness centrality.

Problem: Applying the metrics is not difficult. However, they only take into consideration the weight of the edges (the distance) and not the amount of people working in an office. This should be of course taken into consideration, as otherwise the photocopier will be placed in an office, which is very close to other offices and on many shortest paths, but the total distance of all the people travelling will be too much.

As a solution, I would like to subdivide the office nodes into nodes representing the employees. Thus, people working in the same office are linked with an edge with the weight of zero (they are basically stacked), while each employee has also links to employees of other offices. Based on this new graph I can now calculate the metrics.

I am however not sure, if this is mathematically correct and how I would now transform the employee network metrics back into the office network metrics.

Appreciate your help!

Please find below an example with code:

Concept Here you can see 5 nodes with different weights in brackets.

 import networkx as nx #Generate example graph with 5 nodes G = nx.Graph() G.add_nodes_from([11,21,31,41,51]) #Office-graph G.add_edge(11,21, weight =3) G.add_edge(21,31, weight =2) G.add_edge(31,51, weight =4) G.add_edge(21,41, weight =1) G.add_edge(41,51, weight =5) nx.draw_networkx(G) #Calculate the weighted closeness centrality, CCW = nx.closeness_centrality(G, u=None, distance='weight', wf_improved=True) CCW #devide nodes into subnodes with weight of 1 G.add_node(22) G.add_node(23) G.add_node(24) G.add_node(32) G.add_node(52) #add respective edges G.add_edge(22,23, weight =0) G.add_edge(22,24, weight =0) G.add_edge(23,24, weight =0) G.add_edge(31,32, weight =0) G.add_edge(51,52, weight =0) G.add_edge(21,22, weight =3) G.add_edge(21,23, weight =3) G.add_edge(21,24, weight =3) G.add_edge(21,31, weight =2) G.add_edge(22,31, weight =2) G.add_edge(23,31, weight =2) G.add_edge(24,31, weight =2) G.add_edge(21,32, weight =2) G.add_edge(22,32, weight =2) G.add_edge(23,32, weight =2) G.add_edge(24,32, weight =2) G.add_edge(31,51, weight =4) G.add_edge(32,51, weight =4) G.add_edge(31,52, weight =4) G.add_edge(32,52, weight =4) G.add_edge(21,41, weight =1) G.add_edge(41,51, weight =5) G.add_edge(41,52, weight =5) nx.draw_networkx(G) #Calculate the weighted closeness centrality, CCW_new = nx.closeness_centrality(G, u=None, distance='weight', wf_improved=True) CCW1_new

As I said in the comment above, it seems to me that you want to minimize total distance traveled to the copier. Given the nature of the graph, I would favour a simple, brute-force solution. Here is my approach:

import networkx as nx

from itertools import combinations

#Generate example graph with 5 nodes
G = nx.Graph()
G.add_nodes_from([11,21,31,41,51])

#Office-graph
G.add_edge(11,21, weight=3)
G.add_edge(21,31, weight=2)
G.add_edge(31,51, weight=4)
G.add_edge(21,41, weight=1)
G.add_edge(41,51, weight=5)

# let's make sure we know the correct answer by assigning one office 99% of the workforce
office_to_people = {11: 5, 21: 2, 31: 1000, 41:0, 51:10}

node_to_cost = {ii : 0 for ii in G.nodes}
for source, target in combinations(list(G.nodes), 2):
    path_length = nx.shortest_path_length(G, source, target, weight='weight')
    node_to_cost[source] += office_to_people[target] * path_length
    node_to_cost[target] += office_to_people[source] * path_length

office, minimum_cost = sorted(node_to_cost.items(), key=lambda x: x[1])[0]
print(f"{office}")
# 31 

If you want to factor in non-uniform photocopier use, then this method can be easily extended to do so by simply computing the total photocopier use per office, and substituting office_to_people with an equivalent office_to_total_use .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM