當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Python NetworkX network_simplex用法及代碼示例


本文簡要介紹 networkx.algorithms.flow.network_simplex 的用法。

用法:

network_simplex(G, demand='demand', capacity='capacity', weight='weight')

在有向圖 G 中找到滿足所有需求的最小成本流。

這是一種使用離開弧規則來防止循環的原始網絡單純形算法。

G 是一個有邊成本和容量的有向圖,其中節點有需求,即它們想要發送或接收一定量的流量。負需求意味著節點想要發送流量,正需求意味著節點想要接收流量。如果流入每個節點的淨流量等於該節點的需求,則有向圖 G 上的流量滿足所有需求。

參數

GNetworkX 圖

DiGraph 找到滿足所有需求的最小成本流。

demandstring

圖 G 的節點預計具有一個屬性需求,該屬性指示節點想要發送(負需求)或接收(正需求)多少流量。請注意,需求之和應為 0,否則問題不可行。如果此屬性不存在,則認為節點的需求為 0。默認值:‘demand’。

capacitystring

圖 G 的邊應該有一個屬性容量,表示邊可以支持多少流量。如果此屬性不存在,則認為邊具有無限容量。默認值:‘capacity’。

weightstring

圖 G 的邊應該有一個屬性權重,該屬性權重指示在該邊上發送一個單位的流量所產生的成本。如果不存在,則認為權重為 0。默認值:‘weight’。

返回

flowCost整數,浮點數

滿足所有需求的最小成本流的成本。

flowDict字典

由節點鍵入的字典字典,使得 flowDict[u][v] 是流邊 (u, v)。

拋出

NetworkXError

如果輸入圖未定向或未連接,則會引發此異常。

NetworkXUnfeasible

在以下情況下會引發此異常:

  • 需求之和不為零。那麽,就沒有滿足所有需求的流程。

  • 沒有滿足所有需求的流量。

NetworkXUnbounded

如果有向圖 G 具有負成本和無限容量的循環,則會引發此異常。那麽,滿足所有需求的流程的成本在下麵是無界的。

注意

如果邊權重或需求是浮點數(溢出和舍入錯誤可能導致問題),則不保證此算法有效。作為一種解決方法,您可以通過將相關邊屬性乘以一個方便的常數因子(例如 100)來使用整數。

參考

1

Z. Kiraly, P. Kovacs. Efficient implementation of minimum-cost flow algorithms. Acta Universitatis Sapientiae, Informatica 4(1):67-118. 2012.

2

R. Barr, F. Glover, D. Klingman. Enhancement of spanning tree labeling procedures for network optimization. INFOR 17(1):16-34. 1979.

例子

最小成本流問題的一個簡單示例。

>>> G = nx.DiGraph()
>>> G.add_node("a", demand=-5)
>>> G.add_node("d", demand=5)
>>> G.add_edge("a", "b", weight=3, capacity=4)
>>> G.add_edge("a", "c", weight=6, capacity=10)
>>> G.add_edge("b", "d", weight=1, capacity=9)
>>> G.add_edge("c", "d", weight=2, capacity=5)
>>> flowCost, flowDict = nx.network_simplex(G)
>>> flowCost
24
>>> flowDict
{'a': {'b': 4, 'c': 1}, 'd': {}, 'b': {'d': 4}, 'c': {'d': 1}}

mincost流算法也可以用來解決最短路徑問題。要找到兩個節點 u 和 v 之間的最短路徑,給所有邊一個無限容量,給節點 u 的需求 -1 和節點 v 的需求 1。然後運行網絡單純形。最小成本流的值將是 u 和 v 之間的距離,帶有正流的邊將指示路徑。

>>> G = nx.DiGraph()
>>> G.add_weighted_edges_from(
...     [
...         ("s", "u", 10),
...         ("s", "x", 5),
...         ("u", "v", 1),
...         ("u", "x", 2),
...         ("v", "y", 1),
...         ("x", "u", 3),
...         ("x", "v", 5),
...         ("x", "y", 2),
...         ("y", "s", 7),
...         ("y", "v", 6),
...     ]
... )
>>> G.add_node("s", demand=-1)
>>> G.add_node("v", demand=1)
>>> flowCost, flowDict = nx.network_simplex(G)
>>> flowCost == nx.shortest_path_length(G, "s", "v", weight="weight")
True
>>> sorted([(u, v) for u in flowDict for v in flowDict[u] if flowDict[u][v] > 0])
[('s', 'x'), ('u', 'v'), ('x', 'u')]
>>> nx.shortest_path(G, "s", "v", weight="weight")
['s', 'x', 'u', 'v']

可以更改用於算法的屬性的名稱。

>>> G = nx.DiGraph()
>>> G.add_node("p", spam=-4)
>>> G.add_node("q", spam=2)
>>> G.add_node("a", spam=-2)
>>> G.add_node("d", spam=-1)
>>> G.add_node("t", spam=2)
>>> G.add_node("w", spam=3)
>>> G.add_edge("p", "q", cost=7, vacancies=5)
>>> G.add_edge("p", "a", cost=1, vacancies=4)
>>> G.add_edge("q", "d", cost=2, vacancies=3)
>>> G.add_edge("t", "q", cost=1, vacancies=2)
>>> G.add_edge("a", "t", cost=2, vacancies=4)
>>> G.add_edge("d", "w", cost=3, vacancies=4)
>>> G.add_edge("t", "w", cost=4, vacancies=1)
>>> flowCost, flowDict = nx.network_simplex(
...     G, demand="spam", capacity="vacancies", weight="cost"
... )
>>> flowCost
37
>>> flowDict
{'p': {'q': 2, 'a': 2}, 'q': {'d': 1}, 'a': {'t': 4}, 'd': {'w': 2}, 't': {'q': 1, 'w': 1}, 'w': {}}

相關用法


注:本文由純淨天空篩選整理自networkx.org大神的英文原創作品 networkx.algorithms.flow.network_simplex。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。