1. 程式人生 > >複雜網路-無標度網路matlab程式碼實現

複雜網路-無標度網路matlab程式碼實現

無標度網路是進入研究生,導師丟來的第一個作業,從本科的小小程式猿進入這種乍看一眼非常高大上的東西,還是有些恐懼和興奮的。

由於沒找到中文版的 Emergence of Scaling in Random Networks 就藉助Google翻譯,糙糙看了一下,粗略理解了無標度網路的提出和結構。

論文主要就是diss了隨機網路,yo,yo,隨機網路它太菜,現實生活不會有人愛,你的觀點太直白,還想簡單概括真實世界的舞臺,要我看簡直是胡來,skrskr。

其實隨機網路之所以不能正確描述真實網路,主要是因為現實中的網路具有下面兩種特性

    1。網路是通過新增節點而不斷擴充套件的。
    2。新增的節點會優先連線在連通性更好的節點上。

而根據上面的兩種特性根據論文中的描述實現無標度網路的演算法步驟為: 1。先建立一個小型隨機網路 2。新增節點,並且優先連線在度更大的節點上。

先看如何建立一個隨機網路。首先需要一些初始的節點,先要有節點,才能連線邊,有點有邊才是一個齊齊整整的網路。 程式中設定的初始節點為 5。 有了5個節點,再為每一對節點隨機的連線。

這裡使用的方法是:

用一個鄰接矩陣 作為無向圖的儲存,在這裡就是用來存邊的連線情況,1表示兩個節點之間有邊。 因為1表示有邊,所以可以通過 隨機出一個 0-1之間的小數,然後四捨五入得到非1即0的數字,而且0和1的概率一樣。這樣兩個頂點之間是否有邊就能隨機生成了。

%隨機連邊  1表示有邊
for i=1:m0
    for j= (i+1):m0
        A(i,j)= round(rand());   %非1即0
        A(j,i) =  A(i,j);
    end
end   %初始完成

完成隨機網路後,接下來的工作就是往裡面新增節點。新來的節點就好比是怡紅院新來的小妹妹, 而老節點們自然是都想先‘連線‘一下新來的小妹妹,這裡就要看哪一個老節點以前連線過的小妹妹多了,連線過的越多,活越好,小妹妹越喜歡。這種情況會造成一個現象:富者更富,活好的越來越好,沒經驗的就只能望眼欲穿。

這裡的關鍵是如何根據 度 的大小分配概率,產生 度越大,連線上的概率越大的情況。

先 統計出 每個節點的度,這一步很簡單,鄰接矩陣每一行加起來就行了,matlab中用sum()就能得到所有節點度的集合。 拿到度不夠,我們需要的是構造出一個區間,比如說 1,2,3頂點的度分別是 4,7,1 我們就給 頂點1 : 1-4 (佔4個數字) 頂點2: 4:10 (7個數字) 頂點3: 11-12 (1個數字) 這樣當隨機從1-12中挑一個數字,很明顯,這個數字落在 因為度最大所以得到最大區間的頂點2的區間的概率是最大的。(程式碼就放到最後)

知道要連線的老節點是誰,就OK了,直接把A(新節點,老節點) = A(老節點,新節點)=1 就行了。

迴圈 好 每一個節點之後,就是求度分佈了,畢竟這才是整個步驟的核心。

首先還是計算每個節點的度,得到每個節點的度之後,(假設得到的頂點 1,2,3,4,5的度分別是【2,2,3,4,3】),而我們需要求的是隨便挑選一個頂點它的度是 k 的概率。隨意我們需要知道每個度出現的頻率,即度=2/3/4 出現的概率。

這裡先對頂點的度去重(得到 2,3,4)。 然後 讓  這兩個集合【2,2,3,4,3】 分別 = 2/3/4 這樣每次得到的結果就是 [1,1,0,0,0] [0,0,1,0,1] [0,0,0,1,0] 。 3個集合sum 一下 ,得到 2,2,1 , 這個就是每個度的個數了。說起來拗口,見程式碼就明瞭了。

具體步驟就是這樣了,這是研究生的第一個程式碼。大家多多指教,下一個是小世界網路。

詳細程式碼:

clear all;
tic
m = 5;    %每次加入的邊個數
m0 = 5    %初始的頂點個數
N = 1000;   %最終達到的頂點個數

%建立鄰接矩陣    全0,無邊
A = sparse(N,N);

%隨機連邊  1表示有邊
for i=1:m0
    for j= (i+1):m0
        A(i,j)= round(rand());
        A(j,i) =  A(i,j);
    end
end   %初始完成


%加入的節點為 A(new) , 與其連線的點為old     生成 A(new , old)
for new = m0+1:N
    new
    %old vertice 度越大連線上的概率越大
    Degree = sum(A(1:new-1,1:new-1));  %每個頂點的度
    %製造出一個度的分佈區間,模擬概率
    DegreeInterval(1) = Degree(1);
    for i=2:new-1
        DegreeInterval(i) = Degree(i)+DegreeInterval(i-1);
    end 
    %連線 新節點 與 m個old節點
    AllDegree = sum(sum(A(1:new-1,1:new-1))); %整個圖的總度
    for i = 1:m 
        while 1
         %以概率從old節點中找到合適的頂點連線
         RandDegree  = fix(AllDegree*rand()+1); %要與度區間包含RandDegree的頂點相連
         %找到 符合 要求的區間所屬頂點
         Ans = find(RandDegree <= DegreeInterval(1:new-1));
         old = Ans(1);
         if A(new,old) == 0
            A(new,old) = 1;
            A(old,new) = 1;
            break;         %成功連線
         end
        end
    end
end
    %求度分佈
    Degree = sum(A);  %完成後的網路的每個節點的度  2 3 2 2 4 3
    UniDegree = unique(Degree);  %去重後度       2 3 4
    for i = 1:length(UniDegree)
        DegreeNum(i) = sum(Degree==UniDegree(i));
    end
toc
    %畫圖
   loglog(UniDegree, DegreeNum ./ sum(DegreeNum),'.','markersize',18)
   xlabel('k'),ylabel('P(k)')