无向图的Networkx has_edge仅计数一次

时间:2019-05-15 21:06:13

标签: python graph networkx

我有以下图形:

full_graph = nx.Graph()

tgt_nodes = ['B','F']

full_graph.add_edge('A','B')
full_graph.add_edge('B','C')
full_graph.add_edge('B','D')
full_graph.add_edge('B','E')
full_graph.add_edge('E','F')

#display and save as img
p = nx.drawing.nx_pydot.to_pydot(full_graph)
p.layout = 'spring'

#p.write_png(outputDir+ version+ '//' + 'cluster_no' + str(clusterNo) + '.png')
display.Image(p.create_png())

enter image description here

我正在尝试查找完全是两个连接的所有节点,并根据权重对其进行处理。

out_graph = nx.Graph()

for curr_node in tgt_nodes:

        #find all paths for curr_node that are <=2
        pot_paths = nx.single_source_dijkstra_path_length(full_graph, curr_node,2)
        print(pot_paths)

        #iterate over all potential paths. If length ==2 either increment weight or add with weight = 1
        for pot_node, dist in pot_paths.items():

            if dist == 2:
                print(pot_node)

                if out_graph.has_edge(curr_node, pot_node):

                    # we added this one before, just increase the weight by one. NEED TO LIMIT SO THAT THIS DOESN't TRIGGER ON INVERSES
                    out_graph[curr_node][pot_node]['weight'] += 1
                    print('incremented edge for '+ curr_node)
                else:
                    # new edge. add with weight=1
                    out_graph.add_edge(curr_node, pot_node, weight=1)
                    print('added edge for '+ pot_node)

这应该只触发一次-在B> F的比较中,它应该增加一条边。当它到达F> B时,我不希望它递增,因为它是完全相反的。这是我的结果:

>> {'B': 0, 'A': 1, 'C': 1, 'D': 1, 'F': 2, 'E': 1}
>> F
>> added edge for F
>> {'F': 0, 'B': 2, 'E': 1}
>> B
>> incremented edge for F

out_graph.edges(data = True)

>> EdgeDataView([('F', 'B', {'weight': 2})])

如何修改在同一中间节点上的(F,B)和(B,F)计数一次,而不是两次?

谢谢!

编辑

实际上,这是一个不起作用的示例:

full_graph = nx.Graph()

tgt_nodes = ['B','F']

full_graph.add_edge('A','B')
full_graph.add_edge('B','C')
full_graph.add_edge('B','D')
full_graph.add_edge('B','E')
full_graph.add_edge('E','F')
full_graph.add_edge('G','F')
full_graph.add_edge('B','G')
full_graph.add_edge('F','H')
full_graph.add_edge('B','H')


#display and save as img
p = nx.drawing.nx_pydot.to_pydot(full_graph)
p.layout = 'spring'

#p.write_png(outputDir+ version+ '//' + 'cluster_no' + str(clusterNo) + '.png')
display.Image(p.create_png())

它输出的边沿为2,当应为3时(B和F通过G,E和H连接)

3 个答案:

答案 0 :(得分:2)

是的,如果G是无向的,则如果边缘存在,则G.has_edge(a,b)G.has_edge(b,a)均为True,如果边缘不存在,则False

因此,按照您的代码设置方式,您将两次查看每对节点,并两次执行相同的计算。

如何添加另外一个条件:if G.has_edge(a,b) and a<b:(如果您在有自我优势的情况下这样做,则可能会考虑a<=b)。

然后两次将忽略计算。只要节点定义了比较操作,它就可以工作。因此'A'<1不起作用,但是'A'<'B'返回True

我应该给出的警告是,这仅在确保确保您在两个方向上都能看到每个边缘时,即在两个节点都出现在列表tgt_nodes中的情况下才有效。如果仅显示“更大”节点,则不会计算在内。因此,您可能需要为此优化测试。

答案 1 :(得分:1)

根据@Energya的请求-这是有效的简单代码:

out_graph = nx.bipartite.weighted_projected_graph(full_graph, ['B','F'])

答案 2 :(得分:0)

您根据sbyte确定路径长度,但将边线添加到full_graph。将(B,F)边添加到out_graph之后,它在out_graph中仍然不存在。毕竟,您的full_graph被初始化为空。这也是为什么您的out_graph末尾仅包含一个边(B,F)的原因。

如果您的目标是更新原始文档,则应将out_graph初始化为out_graph的副本,然后进行所有计算。根据您的需要,networkx的内置out_graph = full_graph.copy()可能会达到目的,否则,您应该研究Python的copy.deepcopy()