【问题标题】:Networkx: connecting nodes using portsNetworkx:使用端口连接节点
【发布时间】:2019-11-27 11:10:34
【问题描述】:

我有这个网络:

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')]

前一个产生下一个拓扑。

如您所见,每个节点都有自己的端口p1p2。我知道如何在图中创建这些边或连接:

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

不过,我最感兴趣的是使用每个节点的端口作为连接点。含义:

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

我怎样才能做到这一点?或者,换句话说,我该如何建模,在节点+端口的意义上,锚点最终是这些端口?

谢谢!

【问题讨论】:

    标签: python-3.x networkx


    【解决方案1】:

    任何端口连接的通用模型

    首先,您需要将端口作为属性添加到您的节点:

    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'])
    

    所以,现在如果我执行以下操作:

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

    我得到以下信息:

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

    然后,您基本上可以添加一个包装函数来在图表中创建边。我假设您可以使用从一个节点到另一个节点的任何其他端口的任何端口:

    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)
    

    现在像这样添加边:

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

    要获取锚点列表,只需使用:

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

    现在,如果您确定端口 p1 将始终连接到端口 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)
    

    然后调用:

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

    边缘会是

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

    参考资料:

    【讨论】:

    • 你好@Mohanned!是的,我看到了你的回答,我很喜欢。确实,我一直在考虑类似的事情。到目前为止,我正在这样做nx.set_edge_attributes(G, {(ip_A,ip_B):data}),其中data 与您的“锚点”相同。这种方法的唯一问题是您将锚端口记录为边缘属性。我看到了它的用处,但它并没有解决我的问题。我希望端口本身成为锚点,就像一个节点。无论如何谢谢... !!
    猜你喜欢
    • 1970-01-01
    • 2021-11-18
    • 2014-01-21
    • 2021-04-18
    • 2016-04-29
    • 2011-01-23
    • 1970-01-01
    • 1970-01-01
    • 2022-10-04
    相关资源
    最近更新 更多