基本概念
圖
定義: 圖G(V,E)是指一個二元組(V(G),E(G)),其中:
- 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 官網