NetworkX用法之三——網路演化…
NetworkX提供了4種常見網路的建模方法,分別是:規則圖,ER隨機圖,WS小世界網路和BA無標度網路。本文首先介紹在NetworkX生成這些網路模型的方法,然後以BA無標度網路的建模為例,分析利用NetworkX進行復雜網路演化模型設計的基本思路,以便將來開發出我們自己的模型。同時這篇文章裡還涉及到一點複雜網路視覺化的方法(後邊有時間會另文介紹網路視覺化的方法)。
一、規則圖
規則圖差不多是最沒有複雜性的一類圖了,在NetworkX中,用random_graphs.random_regular_graph(d, n)方法可以生成一個含有n個節點,每個節點有d個鄰居節點的規則圖。下面是一段示例程式碼,生成了包含20個節點、每個節點有3個鄰居的規則圖:
import networkx as nx
import matplotlib.pyplot as plt
RG = nx.random_graphs.random_regular_graph(3,20)
#生成包含20個節點、每個節點有3個鄰居的規則圖RG
pos =
nx.spectral_layout(RG)
#定義一個佈局,此處採用了spectral佈局方式,後變還會介紹其它佈局方式,注意圖形上的區別
nx.draw(RG,pos,with_labels=False,node_size = 30)
#繪製規則圖的圖形,with_labels決定節點是非帶標籤(編號),node_size是節點的直徑
plt.show() #顯示圖形
執行結果如下:
圖1 NetworkX生成的規則圖
二、ER隨機圖
ER隨機圖是早期研究得比較多的一類“複雜”網路,這個模型的基本思想是以概率p連線N個節點中的每一對節點。在NetworkX中,可以用random_graphs.erdos_renyi_graph(n,p)方法生成一個含有n個節點、以概率p連線的ER隨機圖:
import networkx as nx
import matplotlib.pyplot as plt
ER = nx.random_graphs.erdos_renyi_graph(20,0.2)
#生成包含20個節點、以概率0.2連線的隨機圖
pos =
nx.shell_layout(ER)
#定義一個佈局,此處採用了shell佈局方式
nx.draw(ER,pos,with_labels=False,node_size = 30)
plt.show()
執行結果如下:
圖2 NetworkX生成的隨機圖
三、WS小世界網路
在NetworkX中,可以用random_graphs.watts_strogatz_graph(n, k, p)方法生成一個含有n個節點、每個節點有k個鄰居、以概率p隨機化重連邊的WS小世界網路,下面是一個例子:
import networkx as nx
import matplotlib.pyplot as plt
WS = nx.random_graphs.watts_strogatz_graph(20,4,0.3)
#生成包含20個節點、每個節點4個近鄰、隨機化重連概率為0.3的小世界網路
pos =
nx.circular_layout(WS)
#定義一個佈局,此處採用了circular佈局方式
nx.draw(WS,pos,with_labels=False,node_size = 30) #繪製圖形
plt.show()
執行結果如下:
圖3 NetworkX生成的WS小世界網路
四、BA無標度網路
在NetworkX中,可以用random_graphs.barabasi_albert_graph(n, m)方法生成一個含有n個節點、每次加入m條邊的BA無標度網路,下面是一個例子:
import networkx as nx
import matplotlib.pyplot as plt
BA= nx.random_graphs.barabasi_albert_graph(20,1)
#生成n=20、m=1的BA無標度網路
pos =
nx.spring_layout(BA)
#定義一個佈局,此處採用了spring佈局方式
nx.draw(BA,pos,with_labels=False,node_size = 30) #繪製圖形
plt.show()
執行結果如下:
圖4 NetworkX生成的BA無標度網路
五、對BA模型實現程式碼的分析
前面我們介紹了NetworkX提供的4種網路演化模型的應用方法,但僅停留在使用已有的模型是不夠的,實際工作中我們可能會自己開發一些網路演化模型。利用NetworkX提供的資料結構,我們可以比較方便的完成這一工作。下面以NetworkX中BA模型的實現程式碼為例,分析用NetworkX開發網路演化模型的一般思路。NetworkX中關於網路建模的程式碼在random_graphs.py這個檔案中,可以用記事本開啟它。為了敘述簡便起見,我刪掉了原始程式碼中的一些錯誤處理與初始條件定義的語句,紅色部分是翻譯後的註釋。
#定義一個方法,它有兩個引數:n - 網路節點數量;m - 每步演化加入的邊數量
def
barabasi_albert_graph(n, m):
# 生成一個包含m個節點的空圖
(即BA模型中t=0時的m0個節點)
G=empty_graph(m)
# 定義新加入邊要連線的m個目標節點
targets=range(m)
#
將現有節點按正比於其度的次數加入到一個數組中,初始化時的m個節點度均為0,所以陣列為空
repeated_nodes=[]
# 新增其餘的
n-m 個節點,第一個節點編號為m(Python的陣列編號從0開始)
source=m
# 迴圈新增節點
while
source<n:
#
從源節點連線m條邊到選定的m個節點targets上(注意targets是上一步生成的)
G.add_edges_from(zip([source]*m,targets))
#
對於每個被選擇的節點,將它們加入到repeated_nodes陣列中(它們的度增加了1)
repeated_nodes.extend(targets)
#
將源點m次加入到repeated_nodes陣列中(它的度增加了m)
repeated_nodes.extend([source]*m)
# 從現有節點中選取m個節點 ,按正比於度的概率(即度優先連線)
targets=set()
while len(targets)<m:
#按正比於度的概率隨機選擇一個節點,見註釋1
x=random.choice(repeated_nodes)
#將其新增到目標節點陣列targets中
targets.add(x)
#挑選下一個源點,轉到迴圈開始,直到達到給定的節點數n
source += 1
#返回所得的圖G
return
G
註釋1:此步是關鍵,random.choice方法是從一個數組中隨機地挑選一個元素。由於repeated_nodes陣列中的節點出現次數是正比於節點度的,所以這樣處理可以保證按度大小的概率選出節點,即實現了度優先連線。如果是按正比於節點適應性等非整數值優先連線,可以參考我的另一篇博文《根據值的大小隨機取陣列元素的方法》。
六、小結
NetworkX的優勢之一就是開源,這也是所有Python庫的優勢(Python是指令碼語言,它沒有辦法隱藏原始碼)。NetworkX的原始碼結構清晰,風格簡練,註釋詳盡,是學習、研究複雜網路不錯的參考資料。當然在這方面我也是初學者,更多的功能還需要在實際應用中不斷去發掘和領會…………