1. 程式人生 > >NetworkX用法之三——網路演化…

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() #顯示圖形


執行結果如下:

[轉載]NetworkX用法之三鈥斺斖繆蓴P停ㄗ

圖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()

執行結果如下:

[轉載]NetworkX用法之三鈥斺斖繆蓴P停ㄗ

圖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()

執行結果如下:

[轉載]NetworkX用法之三鈥斺斖繆蓴P停ㄗ

圖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()

執行結果如下:

[轉載]NetworkX用法之三鈥斺斖繆蓴P停ㄗ

圖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的原始碼結構清晰,風格簡練,註釋詳盡,是學習、研究複雜網路不錯的參考資料。當然在這方面我也是初學者,更多的功能還需要在實際應用中不斷去發掘和領會…………