[英]How to place nodes in a specific position - networkx
我正在做一個 Ford-Fulkerson 方法,它在每個階段繪制圖形。 我想將源和接收器放置在特定位置(我希望源位於圖形的最左側,而接收器位於最右側)。 我已經在spring_layout
函數中嘗試過pos
參數,但這似乎不起作用。
這是我的圖表:
graph.add_edges_from([
('A', 'B', {'capacity': 4, 'flow': 0}),
('A', 'C', {'capacity': 5, 'flow': 0}),
('A', 'D', {'capacity': 7, 'flow': 0}),
('B', 'E', {'capacity': 7, 'flow': 0}),
('C', 'E', {'capacity': 6, 'flow': 0}),
('C', 'F', {'capacity': 4, 'flow': 0}),
('C', 'G', {'capacity': 1, 'flow': 0}),
('D', 'F', {'capacity': 8, 'flow': 0}),
('D', 'G', {'capacity': 1, 'flow': 0}),
('E', 'H', {'capacity': 7, 'flow': 0}),
('F', 'H', {'capacity': 6, 'flow': 0}),
('G', 'H', {'capacity': 4, 'flow': 0}),
])
Ford-Fulkerson 算法:
def ford_fulkerson(graph, source, sink, debug=None):
flow, path = 0, True
while path:
path, reserve = depth_first_search(graph, source, sink)
flow += reserve
for v, u in zip(path, path[1:]):
if graph.has_edge(v, u):
graph[v][u]['flow'] += reserve
else:
graph[u][v]['flow'] -= reserve
if callable(debug):
debug(graph, path, reserve, flow)
def depth_first_search(graph, source, sink):
undirected = graph.to_undirected()
explored = {source}
stack = [(source, 0, dict(undirected[source]))]
while stack:
v, _, neighbours = stack[-1]
if v == sink:
break
while neighbours:
u, e = neighbours.popitem()
if u not in explored:
break
else:
stack.pop()
continue
in_direction = graph.has_edge(v, u)
capacity = e['capacity']
flow = e['flow']
neighbours = dict(undirected[u])
if in_direction and flow < capacity:
stack.append((u, capacity - flow, neighbours))
explored.add(u)
elif not in_direction and flow:
stack.append((u, flow, neighbours))
explored.add(u)
reserve = min((f for _, f, _ in stack[1:]), default=0)
path = [v for v, _, _ in stack]
return path, reserve
ford_fulkerson(graph, 'A', 'H', flow_debug)
這是我使用的布局:
layout = nx.spring_layout(graph, weight='capacity', dim=2, k=20, pos={'A': [-3, -3], 'H': [5, 1]})
這是我得到的結果:
我希望“A”節點位於最左側,“H”節點位於最右側。
我建議您使用帶有 DOT 可視化的 agraph 中的graphviz 布局:
pos=nx.drawing.nx_agraph.graphviz_layout(
graph,
prog='dot',
args='-Grankdir=LR'
)
它強制nx.draw
調用 DOT 程序來獲取圖形布局。 DOT 旨在與有向圖(尤其是非循環圖)一起使用。 在這里,你可以看到這個布局的使用(注意, graphviz
和agraph
必須安裝-python連接器):
nx.draw(
graph,
node_size=2000,
node_color='#0000FF',
arrowsize=50,
with_labels=True,
labels={n: n for n in graph.nodes},
font_color='#FFFFFF',
font_size=35,
pos=nx.drawing.nx_agraph.graphviz_layout(
graph,
prog='dot',
args='-Grankdir=LR'
)
)
檢查spring_layout
的文檔,它說:
pos (dict or None optional (default=None)) – 節點的初始位置作為字典,節點作為鍵,值作為坐標列表或元組。 如果沒有,則使用隨機初始位置。
所以你已經設置了節點的初始位置,但是算法從起始位置移動節點,所以這些變化並不奇怪。
看下一個論點:
固定(列表或無可選(默認=無))– 節點在初始位置保持固定。
因此,您需要使用此可選參數指定哪些節點固定在其初始位置。
節點布局完成后,您將獲得 dict 對象中的所有節點位置(此處為layout
)。 您可以隨時根據需要重新定位其中一些。 在這里,我將節點A
和H
的位置設置在圖形中心的左側和右側 (0,0)。
# fix positions of some nodes
layout['A'] = [-3, -3] # position at left
layout['H'] = [5, 1] # position at right
在這個階段,如果你想把它們從圖形的中心移得更遠,這個簡單的代碼可以處理。
# reposition the nodes further away from center
# need: import numpy as np
xmult = 1.2 # use value greater than 1.0
layout['A'] = layout['A']*np.array([xmult, 1]) # move left
layout['H'] = layout['H']*np.array([xmult, 1]) # move right
最后,當你用
nx.draw_networkx(graph, pos=layout)
你應該得到類似於這樣的情節:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.