复杂网络-无标度网络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 ,这个就是每个度的个数了。2/(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)')
展开阅读全文

没有更多推荐了,返回首页