簡體   English   中英

如何將節點放置在特定位置 - networkx

[英]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 旨在與有向圖(尤其是非循環圖)一起使用。 在這里,你可以看到這個布局的使用(注意, graphvizagraph必須安裝-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 )。 您可以隨時根據需要重新定位其中一些。 在這里,我將節點AH的位置設置在圖形中心的左側和右側 (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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM