[譯] 基於 Python 的圖論和網絡分析

引論

「一張照片包含了萬千信息」,這句話經常被人們引用。可是一張圖能表達的信息要更多。以圖的形式可視化數據,幫助咱們得到了更可行的看法,並基於此做出更好的數據驅動的決策。html

可是,爲了真正理解圖究竟是什麼,以及爲何咱們要使用它,咱們還須要知道圖論的概念。知道了這個,能夠幫助咱們更好的編程。前端

若是你以前曾經學習過圖論,你必定知道你須要學習成千上萬的公式和枯燥的理論概念。因此咱們決定寫這篇博客。咱們會首先解釋概念而後提供說明示例,方便你跟上咱們的進度,並直觀的理解函數是如何運做的。本篇博客會寫的很詳細,由於咱們相信,提供正確的解釋,是一種比只給出簡單定義更受歡迎的選擇。node

在本篇文章中,咱們會了解圖是什麼,它的應用,以及一些圖的歷史。同時文章中也會涵蓋一些圖論概念,而後咱們會學習一個基於 Python 的示例,來鞏固理解。python

準備好了嗎?那咱們開始進入學習吧!android

目錄

  • 圖及圖的應用
  • 圖的歷史以及咱們爲何選擇圖?
  • 你須要知道的術語
  • 圖論基礎概念
  • 熟悉 Python 中的圖
  • 基於數據集的分析

圖及圖的應用

讓咱們先來觀察一個以下所示的簡單的圖,從而幫助理解概念:ios

設想這個圖表明瞭城市中人們常常會光顧的不一樣地點,而後一位城市遊客按照這個路徑行進。咱們設定 V 表示地點,E 表示地點之間的路徑git

V = {v1, v2, v3, v4, v5}

E = {(v1,v2), (v2,v5), (v5, v5), (v4,v5), (v4,v4)}
複製代碼

邊 (u,v) 和邊 (v,u) 是同樣的 —— 它們是無序數對。github

具體來說 —— 圖是一種用來學習對象間和實體間配對關係的數學結構。它是離散數學的一個分支,而且在計算機科學、化學、語言學、運籌學、社會學等多個領域有普遍的應用。正則表達式

數據科學和分析領域也一樣使用圖來模擬不一樣的結構和問題。做爲一個數據學的科學家,你應該可以以高效的方法來解決問題,而在不少場景下,圖就能夠提供這樣高效的機制,由於數據被以一種特別的方式組織了起來。算法

正式來說:

  • 由兩個集合組成。G = (V,E)。V 是一個頂點集合。E 是一個邊的集合。E 是 V 中元素對組合而來的(無序對)。
  • 有向圖也是集合的配對。D = (V,A)。V 是頂點的集合。A 是弧的集合。A 是 V 中元素配對組合(有序對)。

若是是有向圖,那麼 (u,v)(v,u) 就是有區別的。這時,邊被稱爲弧,來代表方向的概念。

R 和 Python 中有不少用圖論來分析數據的庫。在本篇文章中,咱們將會使用 Networkx Python 包來簡單的學習一些這方面的概念,並作一些數據分析。

from IPython.display import Image
Image('images/network.PNG')
複製代碼

Image('images/usecase.PNG')
複製代碼

在上面的例子中能夠很清晰的看出,圖在數據分析中的應用很是普遍。咱們來看幾個案例:

  • 市場分析 —— 圖可以用於找出社交網中最具備影響力的人。廣告商和營銷人員可以經過將信息引導至社交網絡中最有影響力的人那裏,來試圖獲取最大的營銷效益。
  • 銀行交易 —— 圖可以用於找出不一樣尋常的交易者,幫助減小欺詐交易。曾經在不少案例中,恐怖分子的活動都被國際銀行網絡中貨幣流分析監測到了。
  • 供給鏈 —— 圖能幫助找出運送貨物的最優路線,還能幫助選定倉庫和運送中心的位置。
  • 製藥 —— 製藥公司可使用圖論來優化推銷員的路線。這樣能夠幫助推銷員下降成本,並縮短旅途時間。
  • 電信 —— 電信公司一般會使用圖(Voronoi 圖)來計算出信號塔的數量和位置,而且還可以保證最大覆蓋面積。

圖的歷史以及咱們爲何選擇圖?

圖的歷史

若是你想知道圖的理論是如何被創建起來的 —— 繼續讀下去吧!

圖論的起源能夠追溯到七橋(Konigsberg bridge)問題(大約在 1730 年左右)。這個問題提出,哥尼斯堡城裏的七座橋是否可以在知足如下條件的前提下所有被走過一遍:

  • 路徑無重複
  • 路徑結束的地方剛好就是你開始的位置

這個問題等同於,有四節點和七邊的圖是否能擁有一個歐拉圓(歐拉圓指的是,一個開始點和終止點相同的歐拉路徑。而歐拉路徑指的是,在圖中剛好經過每一條邊一次的路徑。更多的術語將在下文介紹)。這個問題引出了歐拉圖的概念。而關於哥尼斯堡橋問題,答案是不能,第一個回答出這個問題的人正是歐拉,你必定已經猜到了。

在 1840 年,A.F Mobius 給出了徹底圖和二分圖的概念,同時 Kuratowski 經過 recreational 問題證實了它們都是平面圖。樹的概念(無環全鏈接圖)則在 1845 被 Gustav Kirchhoff 提出,而且他在計算電網或電路中的電流時使用了圖論的思想。

在 1852 年,Thomas Gutherie 建立了著名的四色問題。然後在 1856 年,Thomas. P. Kirkman 和 William R.Hamilton 共同在多面體上研究圓環,並經過研究如何找出經過指定的每一個點僅一次的路徑,建立了哈密頓圖的概念。1913 年,H.Dudeney 也提到了一個難題。儘管四色問題很早就被提出,而在一個世紀後才被 Kenneth Appel 和 Wolfgang Haken 解答。這個時間才被認爲是圖論的誕生時間。

Caley 研究了微分學的特定分析形式,從而研究樹結構。這在理論化學上已經有了不少應用。這也激發了枚舉圖論的建立。而在 1878 年,Sylvester 在「量子不變量」與代數和分子圖的協變量之間進行了類比時,使用了「圖」這個術語。

在 1941 年,Ramsey 研究了着色問題,從而引出了圖論另外一個分支的定義,即極值圖論。在 1969 年,四色問題被 Heinrich 經過計算機解決。漸進圖的學習也連帶着激發了隨機圖論的發展。圖論和拓撲學的歷史一樣緊密相關,它們之間有不少共同的概念和理論。

Image('images/Konigsberg.PNG', width = 800)
複製代碼

爲何選擇圖?

如下幾點能夠激勵你在平常數據科學問題中使用圖論:

  1. 在處理抽象概念,例如關係和交互問題時,圖是更好的方法。同時,在你思考這些概念時,它也提供了更直觀且可視的方法。而在分析社會關係時,圖也天然成了基礎。
  2. 圖行數據庫已經成爲了很常見的計算機工具,它是 SQL 和 NoSQL 數據庫的替代。
  3. 圖的一種:DAGs(有向無環圖),可以被應用於模型化分析流。
  4. 一些神經網絡框架也使用 DAGs 來對不一樣層的各個操做建模。
  5. 圖論被用來學習和模型化社交網絡、欺詐模型、功率模型、社交媒體中的病毒性和影響力。社交網絡分析(SNA)也許是圖論在數據科學中最有名的應用。
  6. 它被用於聚類算法 —— 最知名的是 K-Means 算法。
  7. 系統動力學也會應用一些圖論的概念 —— 最知名的是循環。
  8. 路徑優化是優化問題的一個子集,它也使用了圖的概念。
  9. 從計算機科學的角度來看 —— 圖讓計算更加高效。和表格數據相比,若是數據以圖的方式排列,一些算法的複雜度可以更低。

你須要知道的術語

在繼續深刻以前,咱們建議你熟悉下面這些術語。

  1. 頂點 uv 被稱爲邊 (u,v)端點end vertices
  2. 若是兩條邊有相同的端點,那麼它們被稱爲平行的
  3. 形如 (v,v) 的邊是一個
  4. 若是一個圖沒有平行邊也沒有環,則它被稱爲簡單圖
  5. 若是一個圖沒有邊,那麼稱這個圖爲Empty)。也就是 E 是空的
  6. 一個圖若是沒有頂點,那麼稱之爲空圖Null Graph)。也就是 VE 全都是空的
  7. 只有一個頂點的圖稱爲平凡圖Trivial graph)
  8. 若是兩條邊有一個公共頂點,則它們是相鄰Adjacent)邊。若是兩個頂點有一條公共邊,則它們是相鄰頂點
  9. 頂點的,寫做d(v),表示以該頂點做爲端點的的數量。按照慣例,環對應端點的度爲邊的兩倍,平行邊分別對應的兩個端點的度都要加
  10. 度爲 1 的頂點稱爲孤立頂點(Isolated Vertices)。d(1) 的頂點是孤立的。
  11. 若是一個圖的邊集包含了全部端點可能組合成的邊,則稱這個圖爲徹底圖(Complete)
  12. 圖中點和邊是有限的,可替換的序列 ViEiViEi 稱爲圖 G = (V,E) 的一個路徑Walk
  13. 若是路徑的開始頂點和結束頂點是不一樣的,那麼稱這個路徑是開放的(Open)。而若是開始頂點和結束頂點相同,則稱爲閉合的(Closed
  14. 每一個邊最多經過一次的跡(Trail)稱爲路徑
  15. 每一個頂點最多經過一次的路徑(Path)稱爲跡(除了閉路)
  16. 閉合的路徑是閉環(Circuit)—— 相似於一個電路

圖論基礎概念

在這個章節中,咱們將會學習一些數據分析相關的有用的概念(內容不分前後)。記住,本文章涉及的內容以外還有不少須要深度學習的概念。如今讓咱們開始吧。

平均路徑長度

全部可能的配對點的平均最短路徑長度。它給圖了一個「緊密」程度的度量,能夠被用於描述網絡中流的快慢/是否易於經過。

BFS 和 DFS

寬度優先搜索深度優先搜索是兩個用於搜索圖中節點的不一樣的算法。它們一般用於查看從已知節點出發,是否能找到某個節點。也被稱爲圖的遍歷

BFS 的目標是依次搜索距離根節點最近的節點以遍歷圖,而 DFS 的目標是依次搜索距離根節點儘量遠的節點,從而遍歷圖。

中心性

它的用途最普遍,而且是網絡分析最重要的概念工具。中心性的目標是找到網絡中最重要的節點。如何定義「重要」能夠多種方式,因此就有不少中心的度量方法。中心性的度量方法自己就有分類(或者說中心度量方法的類別)。有的是經過邊的流量來度量,而有的則經過圖的路徑結構。

一些最多見的應用以下:

  1. 度中心性 —— 第一個也是概念上最簡單的中心性定義。它表示一個點鏈接的邊的數量。在一個有向圖的例子中,咱們則能夠有兩種度中心性的衡量方式。出度和入度的中心性。
  2. 臨近中心性 —— 從該節點出發,到全部節點的平均路徑長度最短。
  3. 中介中心性 —— 該節點出如今另外兩個節點之間最短路徑中的次數。

這些中心性度量各有不一樣,它們的定義能夠應用於不一樣的算法中。總而言之,這意味着會引出大量的定義和算法。

網絡密度

圖中有多少邊的度量。定義會隨着圖的種類以及問題所處的情景而變化。對於一個徹底無向圖,則網絡密度爲 1,而對於一個空圖,度則爲 0。圖的網絡密度在一些場景下也能夠大於一(好比圖中包含環的時候)。

圖形隨機化

一些圖的指標定義也許很容易計算,可是想要弄清楚它們的相關重要性卻並不容易。這時咱們就會用到網絡/圖形隨機化。咱們同時計算當前圖和另外一個隨機生成的類似圖的某個指標。類似性能夠是圖的度和節點數量相等。一般狀況下,咱們會生成 1000 個類似的隨機圖,並計算每一個圖的指標,而後將結果與手頭上的圖的相同指標進行對比,以得出基準概念。

在數據科學領域中,當你嘗試對圖做出某個聲明的時候,將它與隨機生成的圖作對比將會頗有幫助。

熟悉 Python 中的圖

咱們將會使用 Python 的 networkx 工具包。若是你使用的是 Python 的 Anaconda 發行版,則它能夠被安裝在 Anaconda 的根環境下。你也可使用 pip install 來安裝。

下面咱們來看看使用 Networkx 包能作的一些事情。包括引入和建立圖,以及圖的可視化。

建立圖

import networkx as nx

# 建立一個圖
G = nx.Graph() # 如今 G 是空的

# 添加一個節點
G.add_node(1)
G.add_nodes_from([2,3]) # 你也能經過傳入一個列表來添加一系列的節點

# 添加邊
G.add_edge(1,2)

e = (2,3)
G.add_edge(*e) # * 表示解包元組
G.add_edges_from([(1,2), (1,3)]) # 正如節點的添加,咱們也能夠這樣添加邊
複製代碼

點和邊屬性能夠隨着它們的建立被添加,方法是傳入一個包含了點和屬性的字典。

除了一個一個點或者一條一條邊的來建立圖,還能夠經過應用經典的圖操做來建立,例如:

subgraph(G, nbunch)      - 生成由節點集合 nbunch 組成的 G 的子圖
union(G1,G2)             - 求圖的並集
disjoint_union(G1,G2)    - 圖中全部不一樣節點組成的單元
cartesian_product(G1,G2) - 返回笛卡爾積圖(Cartesian product graph)
compose(G1,G2)           - 兩圖中都有的點所組成的圖
complement(G)            - 補圖
create_empty_copy(G)     - 返回同一個圖的空副本
convert_to_undirected(G) - 返回圖的無向形式
convert_to_directed(G)   - 返回圖的有向形式
複製代碼

對於不一樣類別的圖,有單獨的類。例如類 nx.DiGraph() 支持新建有向圖。包含特定路徑的圖也可使用某一個方法直接建立出來。若是想了解全部的建立圖的方法,能夠參見文檔。參考列表在文末給出。

Image('images/graphclasses.PNG', width = 400)
複製代碼

獲取邊和節點

圖的全部邊和節點可使用方法 G.nodes()G.edges() 獲取。單獨的邊和節點可使用括號/下標的方式獲取。

G.nodes()
複製代碼

NodeView((1, 2, 3))

G.edges()
複製代碼

EdgeView([(1, 2), (1, 3), (2, 3)])

G[1] # 與 G.adj[1] 相同
複製代碼

AtlasView({2: {}, 3: {}})

G[1][2]
複製代碼

{}

G.edges[1, 2]
複製代碼

{}

圖形可視化

Networkx 提供了基礎的圖的可視化功能,可是它的主要目標是分析圖而不是圖的可視化。圖的可視化比較難,咱們將會使用專門針對它的特殊工具。Matplotlib 提供了不少方便的函數。可是 GraphViz 則多是最好的工具,由於它以 PyGraphViz 的形式提供了 Python 接口(下面給出了它的文檔連接)。

%matplotlib inline
import matplotlib.pyplot as plt
nx.draw(G)
複製代碼

首先你須要從網站安裝 Graphviz(以下是下載連接)。而後運行 pip install pygraphviz --install-option=" <>。在安裝選項中你須要提供 Graphviz 的庫和依賴的文件夾地址。

import pygraphviz as pgv
d={'1': {'2': None}, '2': {'1': None, '3': None}, '3': {'1': None}}
A = pgv.AGraph(data=d)
print(A) # 這是圖的字符串形式或者簡單展現形式
複製代碼

Output:

strict graph "" {
	1 -- 2;
	2 -- 3;
	3 -- 1;
}
複製代碼

PyGraphviz 提供了對邊和節點的每一個屬性的強大掌控能力。咱們能夠用它獲得很是美觀的可視化圖形。

# 讓咱們建立另外一個圖,咱們能夠控制它每一個節點的顏色
B = pgv.AGraph()

# 設置全部節點的共同屬性
B.node_attr['style']='filled'
B.node_attr['shape']='circle'
B.node_attr['fixedsize']='true'
B.node_attr['fontcolor']='#FFFFFF'

# 建立並設置每一個節點不一樣的屬性(使用循環)
for i in range(16):
	B.add_edge(0,i)
	n=B.get_node(i)
	n.attr['fillcolor']="#%2x0000"%(i*16)
	n.attr['height']="%s"%(i/16.0+0.5)
	n.attr['width']="%s"%(i/16.0+0.5)
B.draw('star.png',prog="circo") # 這行代碼會在本地建立一個 .png 格式的文件。以下所示。

Image('images/star.png', width=650) # 咱們所建立的圖的可視化圖片
複製代碼

一般狀況下,可視化被認爲是圖分析的一個獨立任務。分析後的圖形會導出爲點文件。而後這個點文件被另作可視化處理,來展現咱們試圖證實的觀點。

基於數據集的分析

咱們將會學習一個通用數據集(並非專門用於圖分析的),而後作一些操做(使用 panda 庫),這樣數據才能以邊列表的形式被插入到圖中。邊列表是一個元組的列表,包含了定義每一條邊的頂點對。

這個數據集來自於航空業。它包含了航線的一些基本信息,以及旅程和目的地的資源,對於每一個旅程還包含了幾欄到達和起飛時間的說明。你可以想象,這個數據集自己就很是適合做爲圖來分析。想象一下航線(邊)鏈接城市(節點)。若是你在運營航空公司,接下來你能夠問以下這幾個問題

  1. 從 A 到 B 的最近路程是什麼?路程最短的是哪條?時間最短的是哪條?
  2. 從 C 到 D 有路徑能夠經過嗎?
  3. 哪些機場的交通壓力最大?
  4. 處於最多機場之間的是哪一個機場?那麼它就能夠做爲當地樞紐
import pandas as pd
import numpy as np

data = pd.read_csv('data/Airlines.csv')
複製代碼
data.shape
(100, 16)
複製代碼
data.dtypes

year                int64
month               int64
day                 int64
dep_time          float64
sched_dep_time      int64
dep_delay         float64
arr_time          float64
sched_arr_time      int64
arr_delay         float64
carrier            object
flight              int64
tailnum            object
origin             object
dest               object
air_time          float64
distance            int64
dtype: object
複製代碼
  1. 咱們注意到,將起始點和終點做爲節點是一個很好的選擇。這樣全部的信息均可以做爲節點或者邊的屬性了。一條邊能夠被認爲是一段旅程。這段旅程將會和不一樣的時間、航班號、飛機尾號等等相關聯。
  2. 咱們注意到,年月日和其餘時間信息被分散在好幾欄中。咱們但願建立一個能包含全部這些信息時間欄,咱們也須要分別保存預計和實際的到達和出發時間。最終,咱們應該有 4 個時間欄(預計和實際的到達和出發時間)
  3. 另外,時間欄的格式並不合適。下午的 4:30 被表示爲 1630 而不是 16:30。該欄中並無分隔符來分割信息。其中一個方法是使用 pandas 庫的字符串方法和正則表達式。
  4. 咱們也要注意,sched_dep_time 和 sched_arr_time 是 int64 數據類型的,而 dep_time 和 arr_time 是 float64 數據類型的
  5. 另外一個複雜的因素是 NaN 值
# 將 sched_dep_time 轉化爲 'std' —— 預計起飛時間
data['std'] = data.sched_dep_time.astype(str).str.replace('(\d{2}$)', '') + ':' + data.sched_dep_time.astype(str).str.extract('(\d{2}$)', expand=False) + ':00'

# 將 sched_arr_time 轉化爲 'sta' —— 預計抵達時間
data['sta'] = data.sched_arr_time.astype(str).str.replace('(\d{2}$)', '') + ':' + data.sched_arr_time.astype(str).str.extract('(\d{2}$)', expand=False) + ':00'

# 將 dep_time 轉化爲 'atd' —— 實際起飛時間
data['atd'] = data.dep_time.fillna(0).astype(np.int64).astype(str).str.replace('(\d{2}$)', '') + ':' + data.dep_time.fillna(0).astype(np.int64).astype(str).str.extract('(\d{2}$)', expand=False) + ':00'

# 將 arr_time 轉化爲 'ata' —— 實際抵達時間
data['ata'] = data.arr_time.fillna(0).astype(np.int64).astype(str).str.replace('(\d{2}$)', '') + ':' + data.arr_time.fillna(0).astype(np.int64).astype(str).str.extract('(\d{2}$)', expand=False) + ':00'
複製代碼

如今咱們有了咱們指望的格式時間欄。最後,咱們指望將yearmonthday 合併爲一個時間欄。這一步並非必需的,可是一旦時間被轉化爲 datetime 的格式,咱們能夠很容易的獲取到年月日以及其餘信息。

data['date'] = pd.to_datetime(data[['year', 'month', 'day']])

# 最後,咱們刪除掉不須要的欄
data = data.drop(columns = ['year', 'month', 'day'])
複製代碼

如今使用 networkx 函數導入數據,該函數能夠直接獲取 pandas 的數據幀。正如圖的建立,這裏也有不少將不一樣格式的數據插入圖的方法。

import networkx as nx
FG = nx.from_pandas_edgelist(data, source='origin', target='dest', edge_attr=True,)
複製代碼
FG.nodes()
複製代碼

輸出:

NodeView(('EWR', 'MEM', 'LGA', 'FLL', 'SEA', 'JFK', 'DEN', 'ORD', 'MIA', 'PBI', 'MCO', 'CMH', 'MSP', 'IAD', 'CLT', 'TPA', 'DCA', 'SJU', 'ATL', 'BHM', 'SRQ', 'MSY', 'DTW', 'LAX', 'JAX', 'RDU', 'MDW', 'DFW', 'IAH', 'SFO', 'STL', 'CVG', 'IND', 'RSW', 'BOS', 'CLE'))
複製代碼
FG.edges()
複製代碼

輸出:

EdgeView([('EWR', 'MEM'), ('EWR', 'SEA'), ('EWR', 'MIA'), ('EWR', 'ORD'), ('EWR', 'MSP'), ('EWR', 'TPA'), ('EWR', 'MSY'), ('EWR', 'DFW'), ('EWR', 'IAH'), ('EWR', 'SFO'), ('EWR', 'CVG'), ('EWR', 'IND'), ('EWR', 'RDU'), ('EWR', 'IAD'), ('EWR', 'RSW'), ('EWR', 'BOS'), ('EWR', 'PBI'), ('EWR', 'LAX'), ('EWR', 'MCO'), ('EWR', 'SJU'), ('LGA', 'FLL'), ('LGA', 'ORD'), ('LGA', 'PBI'), ('LGA', 'CMH'), ('LGA', 'IAD'), ('LGA', 'CLT'), ('LGA', 'MIA'), ('LGA', 'DCA'), ('LGA', 'BHM'), ('LGA', 'RDU'), ('LGA', 'ATL'), ('LGA', 'TPA'), ('LGA', 'MDW'), ('LGA', 'DEN'), ('LGA', 'MSP'), ('LGA', 'DTW'), ('LGA', 'STL'), ('LGA', 'MCO'), ('LGA', 'CVG'), ('LGA', 'IAH'), ('FLL', 'JFK'), ('SEA', 'JFK'), ('JFK', 'DEN'), ('JFK', 'MCO'), ('JFK', 'TPA'), ('JFK', 'SJU'), ('JFK', 'ATL'), ('JFK', 'SRQ'), ('JFK', 'DCA'), ('JFK', 'DTW'), ('JFK', 'LAX'), ('JFK', 'JAX'), ('JFK', 'CLT'), ('JFK', 'PBI'), ('JFK', 'CLE'), ('JFK', 'IAD'), ('JFK', 'BOS')])
複製代碼
nx.draw_networkx(FG, with_labels=True) # 圖的快照。正如咱們指望的,咱們看到了三個很繁忙的機場
複製代碼

nx.algorithms.degree_centrality(FG) # Notice the 3 airports from which all of our 100 rows of data originates
nx.algorithms.degree_centrality(FG) # 從一百多行的全部源數據中標註出這三個機場
nx.density(FG) # 圖的平均邊度
複製代碼

輸出:

0.09047619047619047
複製代碼
nx.average_shortest_path_length(FG) # 圖中全部路徑中的最短平均路徑
複製代碼

輸出:

2.36984126984127
複製代碼
nx.average_degree_connectivity(FG) # 對於一個度爲 k 的節點 —— 它的鄰居節點的平均值是什麼?
複製代碼

輸出:

{1: 19.307692307692307, 2: 19.0625, 3: 19.0, 17: 2.0588235294117645, 20: 1.95}
複製代碼

很明顯的能夠從上文的圖的可視化看出 —— 一些機場之間有不少路徑。加入咱們但願計算兩個機場之間可能的最短路徑。咱們能夠想到這幾種方法

  1. 距離最短路徑
  2. 時間最短路徑

咱們能作的是,經過對比距離或者時間路徑,計算最短路徑的算法。注意,這是一個近似的答案 —— 實際須要解決的問題是,當你到達起色機場時可選擇的航班 + 等待起色的時間共同決定的最短方法。這是一個更加複雜的方法,而也是人們一般用於計劃旅行的方法。鑑於本篇文章的目標,咱們僅僅假設當你到達機場的時候航班剛好能夠搭乘,並在計算最短路徑的時候以時間做爲計算對象。

咱們以 JAX 和 DFW 機場爲例:

# 找到全部可用路徑
for path in nx.all_simple_paths(FG, source='JAX', target='DFW'):
	print(path)

# 站到從 JAX 到 DFW 的 dijkstra 路徑
# 你能夠在這裏閱讀更多更深刻關於 dijkstra 是如何計算的信息 —— https://courses.csail.mit.edu/6.006/fall11/lectures/lecture16.pdf
dijpath = nx.dijkstra_path(FG, source='JAX', target='DFW')
dijpath
複製代碼

輸出:

['JAX', 'JFK', 'SEA', 'EWR', 'DFW']
複製代碼
# 咱們來試着找出飛行時間的 dijkstra 路徑(近似狀況)
shortpath = nx.dijkstra_path(FG, source='JAX', target='DFW', weight='air_time')
shortpath
複製代碼

輸出:

['JAX', 'JFK', 'BOS', 'EWR', 'DFW']
複製代碼

總結

本文只是對圖論與網絡分析這一很是有趣的領域進行了很簡單的介紹。圖論的知識和 Python 包能做爲任何一個數據科學家很是有價值的工具。關於上文使用的數據集,還有一系列能夠提出的問題,例如:

  1. 已知費用、飛行時間和可搭乘的航班,找到兩個機場間的最短距離?
  2. 若是你正管理一家航空公司,而且你有一批飛機。你能夠知道人們對航班的需求。你有權再操做兩駕飛機(或者在你的機隊中增長兩架),你將使用那兩條線路來獲取最大盈利?
  3. 你能不能從新安排航班和時間表,來優化某個特定的參數(例如時間合理性或者盈利能力)

若是你真的解決了這些問題,請在評論區評論,好讓咱們知道!

網絡分析將會幫助咱們解決一些常見的數據科學問題,並以更大規模和抽象的方式進行可視化。若是你想在某個特定方面瞭解更多,請留言給咱們。

參考書目和引用

  1. History of Graph Theory || S.G. Shrinivas et. al
  2. Big O Notation cheatsheet
  3. Networkx reference documentation
  4. Graphviz download
  5. Pygraphvix
  6. Star visualization
  7. Dijkstra Algorithm

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索