Python小白的數學建模課-17.條件最短路徑



  • 條件最短路徑問題,指帶有約束條件、限制條件的最短路徑問題。例如: 頂點約束,包括必經點或禁止點的限制; 邊的約束,包括必經路段、禁行路段和單向路段;無權路徑長度的限制,如要求經過幾步或不超過幾步到達終點。
  • 本文基於 NetworkX 工具包,建立了一個遍歷簡單路徑、判斷約束條件的通用框架。
  • 數模競賽真題案例,詳解禁止點、禁止邊、必經點、必經邊的約束條件處理,進而可以擴展到任何約束條件。
  • 『Python小白的數學建模課 @ Youcans』帶你從數模小白成為國賽達人。


1. 帶有條件約束的最短路徑問題

最短路徑問題是圖論中求兩個頂點之間的最短路徑問題,通常是求最短加權路徑。

在數模競賽中,一般不會直接求最短路徑,那就太簡單了,總是要在基本問題中設置各種限制條件,情況就完全不同了。

條件最短路徑問題,指帶有約束條件、限制條件的最短路徑問題。例如: 頂點約束,包括必經點或禁止點的限制; 邊的約束,包括必經路段、禁行路段和單向路段;無權路徑長度的限制,如要求經過幾步或不超過幾步到達終點。

進一步地,還有雙目標限制的最短路徑問題,求最短長度中花費最小的路線;交通限制條件下的最短路徑問題,如轉向限制、道路交叉口的時間延誤的約束。

求解帶有限制條件的最短路徑問題,總體來說可以分為兩類基本方法:
一類是基於不帶限制條件的最短路徑算法,對求解過程中的每一條有效路徑,都用限制條件進行判斷,如果滿足所有限制條件則繼續,如果不滿足限制條件則放棄該路徑;
另一類方法是基於具體問題和選擇算法的特點,將問題轉化為有約束的規划問題來處理。

但是,如果使用 NetworkX 求解帶有限制條件的最短路徑問題,采用這兩類方法都會有一些困難。原因在於前文所介紹的 NetworkX 提供的 Dijkstra 算法、Bellman-Ford 算法、Floyd 算法和啟發式算法 A* 都是封裝函數,沒有提供設置約束條件的選項和接口,因此用戶不能把條件判斷語句加入這些封裝函數的程序內部。

這個問題不僅存在於 Python 語言的 NetworkX 工具包,對於其它計算機語言的工具包也是類似的。自己編程序費時費力,但可以根據需要修改和擴展;直接調用工具包的算法函數非常方便,但不能進行修改或擴展。

不過,NetworkX 可以生成兩個頂點之間的所有簡單路徑,而且可以獲得所有簡單路徑的邊的列表。利用簡單路徑算法,可以通過對約束條件的判斷來求解帶有頂點約束和邊約束的最短路徑問題。



2. 案例:螞蟻的最優路徑分析

2.1 問題描述

蟻巢有若干個儲藏間(圖中圓圈所示),儲藏間之間有路徑相連(路徑拓撲結構如圖所示)。

該圖為無向圖,路徑通行的花費如圖中線路上的數字所示,路徑正反方向通行的花費相同。

要求從起點 N0 到終點 N17 的最優路徑,並需要滿足條件:

  • 必須經過圖中的綠色節點 N7、N12;
  • 必須經過圖中的兩段綠色路段 (N2, N4)、(N13, N14);
  • 必須避開圖中的紅色路段 (N11, N12);
  • 求花費最少的最優路徑。

說明:本案例來自西安郵電大學(XUPT)第12屆數學建模競賽賽題,本文進行了改編。

2.2 圖的創建和可視化

2.2.1 Python 例程(NetworkX)

# mathmodel17_v1.py
# Demo17 of mathematical modeling algorithm
# Demo of shortest path with constraints with NetworkX
# Copyright 2021 YouCans, XUPT
# Crated:2021-07-09

import numpy as np
import matplotlib.pyplot as plt # 導入 Matplotlib 工具包
import networkx as nx  # 導入 NetworkX 工具包

# 問題:螞蟻的最優路徑分析(西安郵電大學第12屆數學建模競賽B題)
gAnt = nx.Graph()  # 創建:空的 無向圖
gAnt.add_weighted_edges_from([(0,1,3),(0,2,1),(0,3,1),
                            (1,2,1),(1,4,1),(1,9,4),
                            (2,3,1),(2,4,2),(2,5,1),
                            (3,5,2),(3,6,2),(3,7,1),
                            (4,5,1),(4,9,1),
                            (5,6,1),(5,9,3),(5,10,1),(5,12,3),
                            (6,7,1),(6,8,2),(6,12,2),(6,13,4),(6,14,3),
                            (7,8,1),
                            (8,14,1),(8,15,3),
                            (9,10,1),(9,11,1),
                            (10,11,1),(10,12,2),
                            (11,12,1),(11,16,1),
                            (12,13,2),(12,16,1),
                            (13,14,1),(13,15,2),(13,16,2),(13,17,1),
                            (14,15,1),
                            (15,17,4),
                            (16,17,1)])  # 向圖中添加多條賦權邊: (node1,node2,weight)

pos={0:(0,8),1:(7,12),2:(6,9),3:(5,6),4:(11,10),5:(14,8),  # 指定頂點位置
     6:(17,6),7:(10,4),8:(19,4),9:(18,12),10:(21,10),11:(28,12),
     12:(25,8),13:(30,7),14:(24,5),15:(29,4),16:(32,10),17:(37,8)}

fig, ax = plt.subplots(figsize=(9, 6))
nx.draw(gAnt, pos, with_labels=True, node_color='cyan', alpha=0.8)
labels = nx.get_edge_attributes(gAnt,'weight')  # 邊的權值
nx.draw_networkx_edge_labels(gAnt,pos,edge_labels=labels, font_color='m')  # 顯示邊的權值
nx.draw_networkx_nodes(gAnt,pos,nodelist=[0,17],node_color='yellow')  # 設置頂點顏色:N1,N17
nx.draw_networkx_nodes(gAnt,pos,nodelist=[7,12],node_color='lime')  # 設置頂點顏色:N7,N12
nx.draw_networkx_edges(gAnt,pos,edgelist=[(2,4),(13,14)],edge_color='lime',width=3)  # 設置指定邊的顏色、寬度
nx.draw_networkx_edges(gAnt,pos,edgelist=[(11,12)],edge_color='r',width=3)  # 設置指定邊的顏色、寬度
plt.show()

2.2.2 程序說明

本段程序繪制網絡圖,包括頂點、邊、邊的權值,特殊頂點和特殊邊的顏色設置。

  1. 圖的創建。本例使用 nx.Graph() 創建無向圖,然后用 gAnt.add_weighted_edges_from() 函數以列表向圖中添加多條賦權邊,每個賦權邊以元組 (node1,node2,weight) 表示。
  2. 圖的繪制。使用 nx.draw() 繪圖時,默認的節點位置並不理想,可以使用 pos 屬性參數指定節點位置。pos 為字典數據類型,按 node:(x_pos,y_pos) 格式設置節點位置。
  3. 顯示邊的權值。使用 nx.draw_networkx_edge_labels() 可以繪制邊的屬性,例程顯示權值屬性 'weight'。
  4. 設置頂點屬性。nx.draw_networkx_nodes() 可以設置頂點的屬性,例如對 nodelist 列表中的節點設置顏色屬性 node_color。
  5. 設置邊的屬性。nx.draw_networkx_edges() 可以設置邊的屬性,例如對 edgelist 列表中的邊設置線寬屬性 width 和顏色屬性 edge_color。


3. NetworkX 求解條件最短路徑問題

3.1 無限制條件的最短路徑

Python 例程(NetworkX):

# 1. 無限制條件的最短路徑
# Dijkstra 算法:兩個指定頂點之間的最短加權路徑
minWPath1 = nx.dijkstra_path(gAnt, source=0, target=17)  # 頂點 0 到 頂點 17 的最短加權路徑
# Dijkstra 算法:兩個指定頂點之間的最短加權路徑的長度
lMinWPath1 = nx.dijkstra_path_length(gAnt, source=0, target=17)  # 最短加權路徑長度
print("\n問題1: 無限制條件")  
print("N0 到 N17 的最短加權路徑: ", minWPath1)
print("N0 到 N17 的最短加權路徑長度: ", lMinWPath1)

運行結果:

問題1: 無限制條件
N0 到 N17 的最短加權路徑:  [0, 2, 5, 10, 11, 16, 17]
N0 到 N17 的最短加權路徑長度:  6

程序說明:

  1. 對於無限制條件的最短路徑問題,NetworkX 提供了 Dijkstra 算法、Bellman-Ford 算法、Floyd 算法和啟發式算法 A* 的函數。
  2. 例程使用 nx.dijkstra_path() 和 nx.dijkstra_path_length() 調用 Dijkstra 算法求兩個指定頂點之間的最短加權路徑和最短加權路徑長度。

3.2 限制條件:禁止點或禁止邊

程序說明:

  1. 禁止點或者禁止邊的處理比較簡單,從圖中刪除對應的禁止頂點或禁止邊即可。當然,也可以在創建圖時就不添加這些禁止點和禁止邊,但這會導致繪圖時也無法反映這些頂點和邊。
  2. 使用 remove_node(n) 刪除指定頂點 n,remove_edge(u,v) 刪除指定的邊 (u,v)。
  3. 使用 remove_nodes_from([n1,...nk]) 刪除多個頂點,remove_edges_from([(u1,v1),...(uk,vk)]) 刪除多條邊。
  4. 本例程中刪除的點和邊與 2.1 的問題描述中的要求不一致,是為了示例刪除函數的使用。下同。

Python 例程:

# 2. 限制條件:禁止點或禁止邊
# 解決方案:從圖中刪除禁止頂點或禁止邊
gAntF = gAnt.copy()
gAntF.remove_node(5)  # 通過頂點標簽 5 刪除頂點
gAntF.remove_edges_from([(11,12), (13,17)])  # 刪除多條邊 (11,12), (13,17)
minWPath2 = nx.dijkstra_path(gAntF, source=0, target=17)  # 頂點 0 到 頂點 17 的最短加權路徑
lMinWPath2 = nx.dijkstra_path_length(gAntF, source=0, target=17)  # 最短加權路徑長度
print("\n問題2: 禁止點或禁止邊的約束")  # youcans @ XUPT
print("N0 到 N17 的最短加權路徑: ", minWPath2)
print("N0 到 N17 的最短加權路徑長度: ", lMinWPath2)

運行結果:

問題2: 禁止點或禁止邊的約束
N0 到 N17 的最短加權路徑:  [0, 3, 6, 12, 16, 17]
N0 到 N17 的最短加權路徑長度:  7

3.3 限制條件:一個必經點

程序說明:

  1. 當限制條件為一個必經點時,可以把原問題分解為兩個子問題:子問題 1 為起點至必經點,子問題 2 為必經點至終點。
  2. 對兩個子問題分別求其最短加權路徑和最短加權路徑長度,然后將兩個子問題的結果合並,就得到經過必經點的原問題的最短加權路徑和最短加權路徑長度。

Python 例程:

# 3. 限制條件:一個必經點
# 解決方案:分解為兩個問題,問題 1 為起點N0至必經點N6,問題 2 為必經點N6至終點N17
gAntP = gAnt.copy()
minWPath3a = nx.dijkstra_path(gAntP, source=0, target=6)  # N0 到 N6 的最短加權路徑
lMinWPath3a = nx.dijkstra_path_length(gAntP, source=0, target=6)  # 最短加權路徑長度
minWPath3b = nx.dijkstra_path(gAntP, source=6, target=17)  # N6 到 N17 的最短加權路徑
lMinWPath3b = nx.dijkstra_path_length(gAntP, source=6, target=17)  # 最短加權路徑長度
minWPath3a.extend(minWPath3b[1:]) # 拼接 minWPath3a、minWPath3b 並去重 N7
print("\n問題3: 一個必經點(N6)的約束")
print("N0 經 N6 到 N17 的最短加權路徑: ", minWPath3a)
print("N0 經 N6 到 N17 的最短加權路徑長度: ", lMinWPath3a+lMinWPath3b)

運行結果:

問題3: 一個必經點(N6)的約束
N0 經 N6 到 N17 的最短加權路徑:  [0, 3, 6, 12, 16, 17]
N0 經 N6 到 N17 的最短加權路徑長度:  7

3.4 限制條件:多個必經點(方案一)

程序說明:

  1. 當限制條件為兩個或多個必經點,如果指定這些必經點的先后順序,可以按 3.3 的方法將原問題分解為多個子問題。
  2. 如果不指定這些比較點的先后順序, 從起點出發不知道應該先去哪個必經點,這是有兩種處理方法:一是用窮舉法對所有可能的順序都進行計算,然后進行比較;二是通過約束條件對所有簡單路徑進行判斷。
  3. NetworkX 提供了 all_simple_paths() 函數,可以生成兩個頂點之間的所有簡單路徑。利用簡單路徑算法,可以通過對約束條件的判斷來求解帶有多個頂點約束的最短路徑問題。
  4. 程序實現的步驟包括:
  • (1)生成指定起點、終點的所有簡單路徑;
  • (2)判斷路徑是否滿足包括所有必經點的限制條件;
  • (3)在滿足限制條件的簡單路徑中找加權長度最短的路徑;
  • (4)求最短路徑的加權路徑長度。
  1. 本段例程非常簡練,綜合使用了幾種 Python 語言循環、判斷結構的簡潔寫法,已經逐句注釋分析,讀者需要認真研讀。

Python 例程:

# 4. 限制條件:多個必經點 (N7,N15)
# 解決方案:遍歷從起點到終點的簡單路徑,求滿足必經點條件的最短路徑
gAntM = gAnt.copy()
minWPath4 = min([path  # 返回 key 為最小值的 path
    for path in nx.all_simple_paths(gAntM, 0, 17)  # gAnt 中所有起點為0、終點為17的簡單路徑
    if all(n in path for n in (7, 15))],  # 滿足路徑中包括頂點 N7,N15
    key=lambda x: sum(gAntM.edges[edge]['weight'] for edge in nx.utils.pairwise(x)))  # key 為加權路徑長度
lenPath4 = sum(gAntM.edges[edge]['weight'] for edge in nx.utils.pairwise(minWPath4))  # 求指定路徑的加權路徑長度
print("\n問題4: 多個必經點(N7, N15)的約束")
print("N0 經 N7, N15 到 N17 的最短加權路徑: ", minWPath4)
print("N0 經 N7, N15 到 N17 的最短加權路徑長度: ", lenPath4)

運行結果:

問題4: 多個必經點(N7, N15)的約束
N0 經 N7, N15 到 N17 的最短加權路徑:  [0, 3, 7, 8, 14, 15, 13, 17]
N0 經 N7, N15 到 N17 的最短加權路徑長度:  8


3.5 限制條件:多個必經點(方案二)

程序說明

  1. 本例與 3.5 的問題實際上是相同的。限制條件都是多個必經頂點 N7、N15,解決方案都是使用 all_simple_paths() 函數生成兩個頂點間的所有簡單路徑,程序實現的步驟也是類似的。
  2. 本方案按照典型的循環、判斷結構的寫法,便於閱讀和理解。此外,如果還有其它約束條件或子任務需要在循環中處理,這樣的結構更容易實現。

Python 例程

# 5. 限制條件:多個必經點 (N7,N15)
# 解決方案:多重循環、判斷結構,遍歷從起點到終點的簡單路徑,求滿足必經點條件的最短路徑
gAntM = gAnt.copy()
lMinWPath5 = minWPath5 = 1e9
for path in nx.all_simple_paths(gAntM, 0, 17):
    if all(n in path for n in (7,15)):  # 滿足路徑中包括頂點 N7,N15
        lenPath = sum(gAntM.edges[edge]['weight'] for edge in nx.utils.pairwise(path))
        if lenPath < lMinWPath5:
            lMinWPath5 = lenPath
            minWPath5 = path
print("\n問題5: 多個必經點(N7, N15)的約束")
print("N0 經 N7, N15 到 N17 的最短加權路徑: ", minWPath5)
print("N0 經 N7, N15 到 N17 的最短加權路徑長度: ", lMinWPath5)

運行結果

問題5: 多個必經點(N7, N15)的約束
N0 經 N7, N15 到 N17 的最短加權路徑:  [0, 3, 7, 8, 14, 15, 13, 17]
N0 經 N7, N15 到 N17 的最短加權路徑長度:  8


3.6 限制條件:必經邊

程序說明

  1. 延續處理多個必經點的思路,生成兩個頂點之間的所有簡單路徑,通過對必經邊約束條件的判斷來求解必經邊約束最短路徑問題。
  2. 本例程的框架和步驟同 3.5,按照典型的循環、判斷結構的寫法,便於閱讀和理解。
  3. all(n in path for n in (2,4,13,14)) 的作用,是判斷路徑中是否包括必經邊 (2,4)、(13,14) 的各頂點,這不僅可以減小計算量,而且能確保下面使用 index() 查找頂點位置時不會發生錯誤。

Python 例程

# 6. 限制條件:必經邊 (N2,N4), (N13,N14)
# 解決方案:遍歷從起點到終點的簡單路徑,求滿足必經邊條件的最短路徑
gAntE = gAnt.copy()
lMinWPath6 = minWPath6 = 1e9  # 置初值
for path in nx.all_simple_paths(gAntE, 0, 17):  # 所有起點為0、終點為17的簡單路徑
    if all(n in path for n in (2,4,13,14)):  # 滿足路徑中包括必經邊的頂點 N2,N4,N13,N14
        # 檢查 (N2,N4)
        p1 = path.index(2)  # N2 的位置
        if (path[p1-1]!=4 and path[p1+1]!=4): continue  # 判斷 N2~N4 是否相鄰
        # 檢查 (N13,N14)
        p2 = path.index(13)  # # N13 的位置
        if (path[p2-1]!=14 and path[p2+1]!=14): continue  # 判斷 N13~N14 是否相鄰
        lenPath = sum(gAntE.edges[edge]['weight'] for edge in nx.utils.pairwise(path))
        if lenPath < lMinWPath6:
            lMinWPath6 = lenPath
            minWPath6 = path
print("\n問題6: 必經邊 (N2,N4), (N13,N14) 的約束")
print("N0 到 N17 的最短加權路徑: ", minWPath6)
print("N0 到 N17 的最短加權路徑長度: ", lMinWPath6)

運行結果

問題6: 必經邊 (N2,N4), (N13,N14) 的約束
N0 到 N17 的最短加權路徑:  [0, 2, 4, 5, 6, 7, 8, 14, 13, 17]
N0 到 N17 的最短加權路徑長度:  10



4. NetworkX 求解螞蟻最優路徑問題

4.1 程序說明

  1. 對於必經點的處理,實際上還可以有更好的方法,即結合 Dijkstra 算法的實現過程, 將限制條件作為縮小搜索空間的條件,可以降低算法的復雜度。但對於多個必經邊來說,很難以此來改進基礎的無約束算法,通常的處理方法就是在算法中增加一個判斷是否滿足約束條件的過程。
  2. 本例程生成兩個頂點之間的所有簡單路徑,通過對各種約束條件的判斷來求解必經邊約束最短路徑問題,可以同時處理禁止點、禁止邊、必經點、必經邊的約束條件。
  3. 本例程對應案例中的各項約束條件: 必須經過圖中的綠色節點;必須經過圖中的兩段綠色路段;必須避開圖中的紅色路段;盡可能以最少的花費到達終點。
  4. 本例程是一個遍歷簡單路徑、判斷約束條件的通用框架。
  5. all(n in path for n in (2,4,7,12,13,14)) 的作用,一是判斷路徑中是否包括必經點 N7、N12;二是判斷路徑中是否包括必經邊 (2,4)、(13,14) 的各頂點,這不僅可以減小計算量,而且能確保下面使用 index() 查找頂點位置時不會發生錯誤。

4.2 Python 例程

# mathmodel17_v1.py
# Demo17 of mathematical modeling algorithm
# Demo of shortest path with constraints with NetworkX
# Copyright 2021 YouCans, XUPT
# Crated:2021-07-09

import numpy as np
import matplotlib.pyplot as plt # 導入 Matplotlib 工具包
import networkx as nx  # 導入 NetworkX 工具包

# 問題:螞蟻的最優路徑分析(西安郵電大學第12屆數學建模競賽B題)
gAnt = nx.Graph()  # 創建:空的 無向圖
gAnt.add_weighted_edges_from([(0,1,3),(0,2,1),(0,3,1),
                            (1,2,1),(1,4,1),(1,9,4),
                            (2,3,1),(2,4,2),(2,5,1),
                            (3,5,2),(3,6,2),(3,7,1),
                            (4,5,1),(4,9,1),
                            (5,6,1),(5,9,3),(5,10,1),(5,12,3),
                            (6,7,1),(6,8,2),(6,12,2),(6,13,4),(6,14,3),
                            (7,8,1),
                            (8,14,1),(8,15,3),
                            (9,10,1),(9,11,1),
                            (10,11,1),(10,12,2),
                            (11,12,1),(11,16,1),
                            (12,13,2),(12,16,1),
                            (13,14,1),(13,15,2),(13,16,2),(13,17,1),
                            (14,15,1),
                            (15,17,4),
                            (16,17,1)])  # 向圖中添加多條賦權邊: (node1,node2,weight)

pos={0:(0,8),1:(7,12),2:(6,9),3:(5,6),4:(11,10),5:(14,8),  # 指定頂點位置
     6:(17,6),7:(10,4),8:(19,4),9:(18,12),10:(21,10),11:(28,12),
     12:(25,8),13:(30,7),14:(24,5),15:(29,4),16:(32,10),17:(37,8)}

fig, ax = plt.subplots(figsize=(9, 6))
nx.draw(gAnt, pos, with_labels=True, node_color='cyan', alpha=0.8)
labels = nx.get_edge_attributes(gAnt,'weight')  # 邊的權值
nx.draw_networkx_edge_labels(gAnt,pos,edge_labels=labels, font_color='m')  # 顯示邊的權值
nx.draw_networkx_nodes(gAnt,pos,nodelist=[0,17],node_color='yellow')  # 設置頂點顏色:N1,N17
nx.draw_networkx_nodes(gAnt,pos,nodelist=[7,12],node_color='lime')  # 設置頂點顏色:N7,N12
nx.draw_networkx_edges(gAnt,pos,edgelist=[(2,4),(13,14)],edge_color='lime',width=3)  # 設置指定邊的顏色、寬度
nx.draw_networkx_edges(gAnt,pos,edgelist=[(11,12)],edge_color='r',width=3)  # 設置指定邊的顏色、寬度

# 7. 限制條件:必經點 N7,N12,必經邊 (N2,N4), (N13,N14),禁止邊 (11,12)
# 解決方案:遍歷從起點到終點的簡單路徑,求滿足必經邊條件的最短路徑
gAntS = gAnt.copy()
gAntS.remove_edge(11,12)  # 刪除禁止邊 (11,12)
lMinWPath = minWPath = 1e9  # 置初值
for path in nx.all_simple_paths(gAntS, 0, 17):  # 所有起點為0、終點為17的簡單路徑
    if all(n in path for n in (2,4,7,12,13,14)): # 滿足路徑中包括頂點 N7,N12
        # 檢查 (N2,N4)
        p1 = path.index(2)  # N2 的位置
        if (path[p1-1]!=4 and path[p1+1]!=4): continue  # 判斷 N2~N4 是否相鄰
        # 檢查 (N13,N14)
        p2 = path.index(13)  # # N13 的位置
        if (path[p2-1]!=14 and path[p2+1]!=14): continue  # 判斷 N13~N14 是否相鄰
        lenPath = sum(gAntS.edges[edge]['weight'] for edge in nx.utils.pairwise(path))
        if lenPath < lMinWPath:
            lMinWPath = lenPath
            minWPath = path

print("\n螞蟻最優路徑問題(帶有禁止點、禁止邊、必經點、必經邊的約束條件)")
print("約束條件:必經點 N7,N12,必經邊 (N2,N4), (N13,N14),禁止邊 (11,12)")
print("N0 到 N17 的最短加權路徑: ", minWPath)
print("N0 到 N17 的最短加權路徑長度: ", lMinWPath)

edgeList = []
for i in range(len(minWPath)-1):
    edgeList.append((minWPath[i],minWPath[i+1]))
nx.draw_networkx_edges(gAnt,pos,edgelist=edgeList,edge_color='b',width=4)  # 設置邊的顏色
plt.show()


4.3 運行結果

螞蟻最優路徑問題(帶有禁止點、禁止邊、必經點、必經邊的約束條件)
約束條件:必經點 N7,N12,必經邊 (N2,N4), (N13,N14),禁止邊 (11,12)
N0 到 N17 的最短加權路徑:  [0, 2, 4, 5, 6, 7, 8, 14, 13, 12, 16, 17]
N0 到 N17 的最短加權路徑長度:  13



5. 總結

  1. 數模競賽中的最短路徑問題,往往是帶有約束條件的最短路徑問題。
  2. 很多計算機語言算法工具包(包括但不限於 Python)都對算法進行了封裝,沒有提供設置約束條件的選項和接口,因此用戶不能把條件判斷語句加入這些封裝函數的程序內部。
  3. 本文基於 NetworkX 工具包,建立了一個遍歷簡單路徑、判斷約束條件的通用框架,不僅可以處理禁止點、禁止邊、必經點、必經邊的約束條件處理,而且可以擴展到任何約束條件。

【本節完】


版權聲明:

歡迎關注『Python小白的數學建模課 @ Youcans』 原創作品

原創作品,轉載必須標注原文鏈接:(https://www.cnblogs.com/youcans/p/15155194.html)。

Copyright 2021 Youcans, XUPT

Crated:2021-07-10


歡迎關注 『Python小白的數學建模課 @ Youcans』,每周更新數模筆記
Python小白的數學建模課-01.新手必讀
Python小白的數學建模課-02.數據導入
Python小白的數學建模課-03.線性規划
Python小白的數學建模課-04.整數規划
Python小白的數學建模課-05.0-1規划
Python小白的數學建模課-06.固定費用問題
Python小白的數學建模課-07.選址問題
Python小白的數學建模課-09.微分方程模型
Python小白的數學建模課-10.微分方程邊值問題
Python小白的數學建模課-12.非線性規划
Python小白的數學建模課-15.圖論的基本概念
Python小白的數學建模課-16.最短路徑算法
Python小白的數學建模課-17.條件最短路徑
Python小白的數學建模課-B2.新冠疫情 SI模型
Python小白的數學建模課-B3.新冠疫情 SIS模型
Python小白的數學建模課-B4.新冠疫情 SIR模型
Python小白的數學建模課-B5.新冠疫情 SEIR模型
Python小白的數學建模課-B6.改進 SEIR疫情模型


免責聲明!

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



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