I recently started using network X and have the following problem.
I have a weighted graph:
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.