Reputation: 75
I have 2 lists:
source_nodes = ['A', 'B', 'C', 'D','D']
dest_nodes = ['P', 'P', 'R', 'S', 'S']
I added edges between the lists' elements using MultiGraph()
(it didn't work with DiGraph()
and I don't know why). What I do is:
for u,v in zip(source_nodes, dest_nodes):
G.add_edge(u, v)
But when I try to get the nodes it removes the duplicates, I get:
['A', 'B', 'C', 'D','P', 'R', 'S']
instead of ['A', 'B', 'C', 'D','D','P', 'P', 'R', 'S', 'S']
Since I need all of them for later computations, how can I get the expected results?
Upvotes: 1
Views: 1913
Reputation: 8811
My assumptions based on your question description:
[A, A, B, C]
, then even though the first and second nodes have same name A
, they are to be treated as if they are separate nodes, like A_1
and A_2
for your later computation.As other answers have pointed out, you can't use duplicate nodes directly in your graph.
However, if you still want to treat the duplicate entries as separate nodes, you can assign unique IDs to each node, and then add them to the graph. Just remember to store the mapping somewhere, so that you can use it later, to extract the original name for say drawing nodes, etc.
import networkx as nx
import uuid
source_nodes = ['A', 'B', 'C', 'D','D']
dest_nodes = ['P', 'P', 'R', 'S', 'S']
def update_mapping(uuid_mapping, node_list):
# This will contain the unique IDs of the nodes
unique_node_list = []
for node in node_list:
# Create unique ID for node
unique_name = uuid.uuid4()
# Add the unique ID to the list
unique_node_list.append(unique_name)
# Update the mapping
uuid_mapping[unique_name]=node
return unique_node_list
# The key is the new unique ID, while the value is the old value
uuid_mapping = {}
# Since dictionaries are mutable in Python, you don't need to
# return and assign them explicitly.
new_source_nodes = update_mapping(uuid_mapping, source_nodes)
new_dest_nodes = update_mapping(uuid_mapping, dest_nodes)
You can check out the unique mapping for each node, just to verify .
print(uuid_mapping)
# {UUID('0bea8e06-51cc-4a22-b0f3-5e7e8884c2f6'): 'A',
# UUID('1a0799aa-d895-4e09-92ac-6fc21a68e2bb'): 'P',
# UUID('334f0bff-c56c-4717-8582-6226a9a0bfb1'): 'C',
# UUID('5727aa18-ae11-4554-bbe9-31b8c0d1f114'): 'P',
# UUID('62155bac-f47f-4b4d-83c7-efd5a27d5f8d'): 'R',
# UUID('acff9155-c2c7-4889-a7f2-dd795b16784a'): 'S',
# UUID('b62324c3-a918-410b-9cae-4d1f87044a88'): 'D',
# UUID('b64eb741-68a2-4082-b68a-bce1150de9dd'): 'D',
# UUID('ba3998fd-3227-44fe-990e-dd3e1bcee259'): 'B',
# UUID('ede62a20-a391-4303-8648-0650f0a3a149'): 'S'}
Notice there are 2 keys with values as D
, S
, and P
.
Now you can use the new_source_nodes
and new_dest_nodes
to create a graph
G = nx.DiGraph()
for u,v in zip(new_source_nodes, new_dest_nodes):
G.add_edge(u, v)
Then, suppose you want to visualize the graph, pass the uuid_mapping
dict as labels
for nodes
pos = nx.spring_layout(G)
nx.draw(G, pos=pos,labels=uuid_mapping)
You can view the working code on Google Colab Notebook here.
References:
Upvotes: 0
Reputation: 672
It is not possible to have the same Note multiple times. But when you implement your Graph with G = networkx.MultiGraph()
you will automatically get all edges, already including the duplicate edges. So you get only 1 D
and 1 S
, but they will be connected with 2 edges
Code:
G = nx.MultiGraph()
source_nodes = ['A', 'B', 'C', 'D','D']
dest_nodes = ['P', 'P', 'R', 'S', 'S']
for u,v in zip(source_nodes, dest_nodes):
G.add_edge(u, v)
for i in G.nodes:
print(i, G.edges(i))
Output:
A -> [('A', 'P')]
P -> [('P', 'A'), ('P', 'B')]
B -> [('B', 'P')]
C -> [('C', 'R')]
R -> [('R', 'C')]
D -> [('D', 'S'), ('D', 'S')]
S -> [('S', 'D'), ('S', 'D')]
Upvotes: 1