C语言 实现小世界网络
write by ai
原文:CSDN 链接 `n## 1简介:
小世界网络最早由Watts和Strogtz在1998年提出,小世界网络存在于数学、物理学和社会学中,是一种数学图的模型。在这种图中大部份的结点不与彼此邻接,但大部份结点可以通过任一其它节点经少数几步就可以产生联系。若将一个小世界网络中的点代表一个人,而联机代表人与人之间是相互认识的,则这小世界网络可以反映陌生人通过彼此共同认识的人而起来产生联系关系的小世界现象。(还记得那个著名的六度分隔理论吗?)
在小世界网络之前,人们研究的较多的是较稀疏的邻近耦合网络和随机网络,但是这两种网络都有其局限性(有兴趣可以自己查阅资料),不能准确地刻画现实世界的特性。所以小世界网络应运而生,其核心思想是随机化重连,通过随机概率的变化实现了邻近耦合网络到随机网络的过渡,而这个过渡就是小世界网络。
下面介绍这个随机化重连的规则:
1、从规则图开始:考虑一个含有N个点的最近邻耦合网络,它们围成一个环,其中每个节点都与它左右相邻的各K/2节点相连,K是偶数。
2、随机化重连:以概率p随机地从新连接网络中的每个边,取一个点顺时针重连间隔为0点之间的边,一端固定,另一端重连,顺时针一圈之后再重连间隔为1点之间的边(具体这个规则可以看Collective dynamics of ‘small-world’ networks这篇论文)。其中规定,任意两个不同的节点之间至多只能有一条边,并且每一个节点都不能有边与自身相连。
图示:

以上就是构建小世界网络的WS算法,但是这种规则有一个问题,就是会导致一些节点被孤立(因为可能连接节点的边都被重连了而却没有边连接这个节点),有兴趣的可以了解一下另一种NW算法,其核心思想是随机化加边,当然了,写论文的两位也意识到了这个问题,于是他们提出了一个规则来尽可能避免,那就是N»K»ln(N)»1,(关于这个大家可以好好思考一下)。
如果想对小世界有一个比较准确完整的了解,百度是没用的,应该直接看1998年那篇论文:Collective dynamics of ‘small-world’ networks。需要的可以留言。
2最短路径:
在构建小世界网络时不可避免的要计算点对之间的最短路径,这里介绍Floyd算法,这个算法虽然时间复杂度有些大O(n^3),但是其简洁深刻真是我印象深刻,其真正核心的代码用C语言描述也只有5行!关于Floyd算法可以百度更多信息,这里不做更多介绍。
3构建思路:
实现确定思路是很重要的,这里我选择在栈外开辟一个较大的数组来描述连接情况,简单的思路表述如下图:

4编程实现:
1、一些预先处理
CSDN_CODE_BLOCK_0_TOKEN 2、主函数CSDN_CODE_BLOCK_1_TOKEN 3、构建最近耦合网络CSDN_CODE_BLOCK_2_TOKEN 4、随机重连CSDN_CODE_BLOCK_3_TOKEN 5、计算最短路径CSDN_CODE_BLOCK_4_TOKEN 6、计算聚类系数CSDN_CODE_BLOCK_5_TOKEN 7、输出数据CSDN_CODE_BLOCK_6_TOKEN
5结果分析
1、聚类系数和最短平均路径随随机化概率p的变化的趋势
、
可以看到随机化概率的增大,最短路径急剧减小而聚类系数缓慢减小,这时候网络在具有较高聚类系数的同时具有较小的平均最短路径,也就是一个小世界网络了。再来看看1998年论文中的原图吧。(默默承认自己的数据取的太少,作图水准太低)

由于数据和编程手段的不同,还是有一些差异的,但是其趋势是明显相同的。
接下来看一下p(随机化重连的概率)取不同值时的连接点对分布



以及p取不同值时的最短平均路径在点对之间的分布(貌似p=0时的图仔细看有好玩的 视觉 错误)






6收获总结
@一定充分构思好再开始敲代码,直接写程序的行为永远是愚蠢的;
@细节问题一定要注意,比如某个矩阵是否更新,细节直接决定成败,没错,是直接。
@一定要找个完整的时间完成,很多事情零零散散完成都是严重影响效率和心情的,最好找个阳光明媚的上午敲完。