我有以下图形:
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())
我正在尝试查找完全是两个连接的所有节点,并根据权重对其进行处理。
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连接)
答案 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()
。