【MATLAB】构建WS小世界网络

分析

进行复杂网络相关研究的基础,就是要构建适当的网络模型。这次选择用Matlab构建一个WS小世界网络练练手。

首先,为了方便数据处理,网络模型我们用邻接矩阵的表示,这样虽然看上去不太直观,但是对于矩阵运算是很友好的。

小世界网络分为两种:NW小世界网络和WS小世界网络。它们的构造都基于一个初试的最近邻耦合网络A:也就是网络中每个节点都与左右相邻的各K/2个节点相连,其中参数K满足N>>K>>lnN>>1(N为网络节点数)。在此基础上,NW小世界网络通过对A进行随机化加边实现网络构造,而WS小世界网络则通过随机的边重连进行网络构造。

WS小世界网络的随机边重连方法也非常容易理解:以概率p对网络中每一条边进行重连,其中新诞生的边必须满足是原网络中没有的边,且节点不能与自己相连。

步骤:

1、为了方便计算,在Matlab中我们用邻接矩阵A来表示网络,A的每一个元素A[m, n]表示节点m和节点n是否相连。

2、构造最近邻耦合网络。明显A是一个对称矩阵,因此我们只需要计算矩阵A的上三角部分(也就是只考虑每个节点与之相连的序号更大的节点),明显对于序号为m的节点来说,从m+1到min(m + K/2, N)的节点都是与它相连的。但是只考虑这部分节点是不全面的,因为对于N=10,K=6的网络来说,2号节点不仅要连接顺时针方向的3、4、5号,也要连接逆时针方向的9、10、1号节点,明显9和10号也属于需要计算的邻接矩阵上三角部分,因此对于节点m而言,满足(m-K/2+N)%N > m的节点也要被考虑在内。可能到这一步大家会很难想到如何去构造这样一个矩阵,但是如果你看到了一个已知最近邻耦合矩阵的样子,一定会豁然开朗。

上图就是N=16,K=8情况下的最近邻耦合矩阵A,很明显的看到:上三角部分刚好为1元素刚好可以构成主对角线往上的前K/2条对角线以及倒数K/2条对角线,因此我们可以直接在零矩阵的基础上直接加上这K条全1的对角线即可。最后,再将矩阵作对称处理。

A = sparse(N, N);
for i = 1 : K/2
    A = A + diag(ones(1,N-i),i);   
    A = A + diag(ones(1, i), N-i);
end
A = A + A';

3、进行随机边重连。

为了后续对生成网络的进一步分析,这里采用不同的p进行随机重连以试验效果。对于一个确定的概率p,我们可以遍历所有的节点,再以概率p确定是否要将它作为待重连边的起点,当然我们也可以给N个节点分配(0, 1)的随机数,再以p作为分界一次性确定所有起点。

StartVs = find(rand(1, N) < p); %通过概率p在N个顶点中随机选择需要重连的边起点

确定了起点后,我们要在该起点所有存在的边中随机选择一条作为旧边,当然,对于邻接矩阵而言,我们要做的是选择该边对应的终点序号;选择好旧终点后,我们也需要确定一个新边对应的新终点,这个终点既不能是起点自身,也不能是与起点已经建立连接的点(因为不允许重复边的出现)。确定后,我们只需要对相应的邻接矩阵值进行更新即可。

值得注意的是,实际的操作中有几点需要注意:确定了起点不一定代表一定可以进行边重连,因为不能够保证起点对应的存在的边,也不一定有起点尚未连接的剩余终点,所以为了避免死循环,我们一定要给随机寻找的过程设置考虑临界条件。对于随机选点的过程,我这里采用在[1, N]取随机数的方法完成,因此为了避免死循环,我设置了两个count分别对新旧终点的找寻进行计数,一旦超过计数值,则默认为不存在满足条件的顶点,直接放弃这次边重连。(之所以可以放弃是因为小世界网络对边重连的次数微动不敏感,并不影响后续的研究)

源码

% WS小世界网络
P = [0, 0.0001, 0.0005, 0.001, 0.005, 0.01, 0.05, 0.1, 0.25, 0.5, 0.75, 0.9, 1];
for p = 1 : length(P) %对每一个P进行随机边重连,以构造不同耦合程度的网络
    This_A = A;
    StartVs = find(rand(1, N) < p); %通过概率p在N个顶点中随机选择需要重连的边起点
    for i = 1 : length(StartVs)
        v1 = StartVs(i);
        %随机找重连边的旧终点
        v2_old = fix(rand * N + 1);
        count_v2_old = N; %计数器,防止死循环
        while v2_old == v1 || This_A(v1, v2_old) ~= 1 
            v2_old = fix(rand * N + 1);
            count_v2_old  = count_v2_old - 1;
            if count_v2_old <= 0
                break;
            end
        end
        %随机找重连边的新终点
        v2_new = fix(rand * N + 1);
        count_v2_new = N; %计数器,防止死循环
        while v2_new == v1 || This_A(v1, v2_new) ~= 0
            v2_new = fix(rand * N + 1);
            count_v2_new  = count_v2_new - 1;
            if count_v2_new <= 0
                break;
            end
        end
        %检查新旧终点是否符合条件,不符合则直接放弃本次重连
        if v2_old == v1 || This_A(v1, v2_old) ~= 1 || v2_new == v1 || This_A(v1, v2_new) ~= 0
            break;
        end
        %检查完毕,进行边重连
        This_A(v1, v2_old) = 0;
        This_A(v2_old, v1) = 0;
        This_A(v1, v2_new) = 1;
        This_A(v2_new, v1) = 1;
    end
   
end  

下面展示一下WS小世界网络边重连的效果。

最近邻耦合网络 N=16,K=8
最近邻耦合网络 N=16 K=8
​​​
p=0.8进行边重连后
​​
​​​​​
  • 8
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值