Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Networkx: connecting nodes using ports

I have this network:

r1 = dict( name  = 'R1', ports = dict(p1 = 'p1', p2 = 'p2') )
r2 = dict( name  = 'R2', ports = dict(p1 = 'p1', p2 = 'p2') )
r3 = dict( name  = 'R3', ports = dict(p1 = 'p1', p2 = 'p2') )
routers = [r1,r2,r3]
G = nx.Graph()
[G.add_node(r['name'], name=r['name']) for r in routers]
G.add_edges_from([('R1','R2'),('R2','R3')]

The previous produces the next topology.

enter image description here

As you can see, each of the nodes have their ports p1 and p2. I know how to create these edges or connections in the graph:

In [53]: G.edges()
Out[53]: EdgeView([('R1', 'R2'), ('R2', 'R3')])

However I'm mostly interested in using the ports of each node as point of connection. Meaning:

In [53]: G.edges()
Out[53]: EdgeView([('R1'.'p1', 'R2'.'p2'), ('R2'.'p1', 'R3'.'p2')])

How can I accomplish that? Or, in other words, how could I model that, in the sense of having nodes+ports where the anchor points are ultimately these ports?

thanks!

like image 569
Lucas Aimaretto Avatar asked Dec 20 '25 23:12

Lucas Aimaretto


1 Answers

Generic model for any port connection

First you need to add the ports as an attribute to your nodes:

import networkx as nx

r1 = dict( name  = 'R1', ports = dict(p1 = 'p1', p2 = 'p2') )
r2 = dict( name  = 'R2', ports = dict(p1 = 'p1', p2 = 'p2') )
r3 = dict( name  = 'R3', ports = dict(p1 = 'p1', p2 = 'p2') )

routers = [r1,r2,r3]

G = nx.Graph()

for r in routers:
  # Add ports as attributes
  G.add_node(r['name'], name=r['name'], ports=r['ports'])

So, now if I do the following:

G.nodes().get('R3', None)

I get the following:

{'name': 'R3', 'ports': {'p1': 'p1', 'p2': 'p2'}}

Then, you can basically add a wrapper function for creating edges in your graph. I have assumed that you can use any port from one node to any other port of another node :

def add_edge_port(G, node1, port1, node2, port2):
  node_list = [node1, node2]
  port_list = [port1, port2]

  edge_ports = []

  for idx in range(0, 2):
    node_idx = node_list[idx]
    port_idx = port_list[idx]

    # Sanity check to see if the nodes and ports are present in Graph
    if G.nodes().get(node_idx, None) is None:
      print("Node : {} is not present in Graph".format(node_idx))
      return

    if G.nodes(data=True)[node_idx]['ports'].get(port_idx, None) is None:
      print("Port ID :{} is incorrect for Node ID : {}!".
            format(node_idx, port_idx))
      return

    edge_ports.append(node_idx + '.' + port_idx)

  # Add the anchor points as edge attributes
  G.add_edge(node1, node2, anchors=edge_ports)

Now add the edges like this:

add_edge_port(G, 'R1', 'p1', 'R2', 'p2')

print(G.edges(data=True))
# Output : EdgeDataView([('R1', 'R2', {'anchors': ['R1.p1', 'R2.p2']})])

To get the anchors list, simply use:

print(nx.get_edge_attributes(G, 'anchors'))
# Output: {('R1', 'R2'): ['R1.p1', 'R2.p2']}

Now if you are sure that port p1 will always connect to port p2

def add_edge_port_modified(G, node1, node2):
  # No need to check the nodes in this case
  edge_ports = [node1 + '.p1', node2 + '.p2'] 
  G.add_edge(node1, node2, anchors=edge_ports)

Then call:

add_edge_port_modified(G, 'R2', 'R3')

and the edges will be

print(nx.get_edge_attributes(G, 'anchors'))
# Output: {('R2', 'R3'): ['R2.p1', 'R3.p2']}

References:

  • https://networkx.github.io/documentation/networkx-2.2/reference/generated/networkx.classes.function.get_edge_attributes.html
like image 72
Gambit1614 Avatar answered Dec 22 '25 21:12

Gambit1614



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!