【python代碼】 最大流問題+最小花費問題+python(ortool庫)實現


基本概念

定義: 圖G(V,E)是指一個二元組(V(G),E(G)),其中:

  1. V(G)={v1,v2,…, vn}是非空有限集,稱為頂點集,
    2. E(G)是V(G)中的元素對(vi,vj)組成的集合稱為邊集。

舉例:
在這里插入圖片描述
V(G)={v1,v2,v3,v4}
E(G)= {e1,e2,e3,e4,e5,e6}


  • 若圖G的邊是有方向的,稱G是有向圖,有向圖的邊稱為有向邊或弧
  • 與同一條邊關聯的兩個端點稱為相鄰的頂點
  • 與同一個頂點關聯的兩條邊稱為相鄰的邊
  • 端點重合為一點的邊稱為
  • 若一對頂點之間有兩條以上的邊聯結,則這些邊稱為重邊
  • 既沒有環也沒有重邊的圖,稱為簡單圖
  • 若圖G的每一條邊e 都賦以一個實數w(e),稱w(e)為邊e的, G連同邊上的權稱為賦權圖 ,
  • 圖G的中頂點的個數, 稱為圖G的階
  • 圖中與某個頂點相關聯的邊的數目,稱為該頂點的度
  • 完全圖:若無向圖的任意兩個頂點之間都存在着一條邊,稱此圖為完全圖。

鄰接矩陣

  • 以下均假設圖為簡單圖,沒有重邊和環
  • 圖G的鄰接矩陣是表示頂點之間相鄰關系的矩陣
    在這里插入圖片描述

舉個例子:
在這里插入圖片描述
在這里插入圖片描述


最大流問題

  • 設G(V,E)為有向圖,若在每條邊e上定義一個非負權c, 則稱圖G為一個網絡,稱c為邊e的容量函數,記為c(e)。

  • 若在有向圖G(V,E)中有兩個不同的頂點vs與vt ,
    若頂點vs只有出度沒有入度,稱vs為圖G的

  • 若頂點vt只有入度沒有出度, 稱vt為G的

  • 若頂點v 既不是源也不是匯, 稱為v中間頂點


在這里插入圖片描述如圖,就是從v1到v9怎么流動,在受每一個有向邊的流動最大限制下,才是最大流。大學考試的內容一般都是用手算的,這里我們還是用python來解決最大流問題。

python解決最大流問題

在這里插入圖片描述

from ortools.graph import pywrapgraph
start_nodes = [0, 0, 0, 1, 1, 2, 2, 3, 3]
end_nodes = [1, 2, 3, 2, 4, 3, 4, 2, 4]
capacities = [20, 30, 10, 40, 30, 10, 20, 5, 20]
max_flow = pywrapgraph.SimpleMaxFlow()
for i in range(0, len(start_nodes)):
    max_flow.AddArcWithCapacity(start_nodes[i], end_nodes[i], capacities[i])
# Find the maximum flow between node 0 and node 4.
if max_flow.Solve(0, 4) == max_flow.OPTIMAL:
    print('Max flow:', max_flow.OptimalFlow())
    print('')
    print('  Arc    Flow / Capacity')
    for i in range(max_flow.NumArcs()):
        print('%1s -> %1s   %3s  / %3s' % (
          max_flow.Tail(i),
          max_flow.Head(i),
          max_flow.Flow(i),
          max_flow.Capacity(i)))
    print('Source side min-cut:', max_flow.GetSourceSideMinCut())
    print('Sink side min-cut:', max_flow.GetSinkSideMinCut())
else:
    print('There was an issue with the max flow input.')

運行結果如下:
在這里插入圖片描述

python解決最大流最小費用問題

跟最大流問題類似,但是每一條邊多了一個費用的概念
在這里插入圖片描述

  • 從圖中可以看到,0點生產了20個貨物,然后要送5個到3,15個到4
  • 一條邊(15,4)意味着這個最多可以運輸15個貨物,每運輸一個貨物就要支付4點費用

from ortools.graph import pywrapgraph
#between each pair. For instance, the arc from node 0 to node 1 has acapacity of 15 and a unit cost of 4.
start_nodes = [ 0, 0,  1, 1,  1,  2, 2,  3, 4]
end_nodes   = [ 1, 2,  2, 3,  4,  3, 4,  4, 2]
capacities  = [15, 8, 20, 4, 10, 15, 4, 20, 5]
unit_costs  = [ 4, 4,  2, 2,  6,  1, 3,  2, 3]
# Define an array of supplies at each node.
supplies = [20, 0, 0, -5, -15]
# Instantiate a SimpleMinCostFlow solver.
min_cost_flow = pywrapgraph.SimpleMinCostFlow()
# Add each arc.
for i in range(0, len(start_nodes)):
    min_cost_flow.AddArcWithCapacityAndUnitCost(start_nodes[i], end_nodes[i],
                                                capacities[i], unit_costs[i])
# Add node supplies.
for i in range(0, len(supplies)):
    min_cost_flow.SetNodeSupply(i, supplies[i])
 # Find the minimum cost flow between node 0 and node 4.
if min_cost_flow.Solve() == min_cost_flow.OPTIMAL:
    print('Minimum cost:', min_cost_flow.OptimalCost())
    print('')
    print('  Arc    Flow / Capacity  Cost')
    for i in range(min_cost_flow.NumArcs()):
      cost = min_cost_flow.Flow(i) * min_cost_flow.UnitCost(i)
      print('%1s -> %1s   %3s  / %3s       %3s' % (
          min_cost_flow.Tail(i),
          min_cost_flow.Head(i),
          min_cost_flow.Flow(i),
          min_cost_flow.Capacity(i),
          cost))
else:
    print('There was an issue with the min cost flow input.')
    

運行結果:
在這里插入圖片描述
參考:
ortool 官網


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM