在网络科学里面有单层的小世界网络,随机网络和无标度网络,在python和matlab中都提供了非常好的函数来供我们使用。但是当我们需要构造多层网络的时候,就需要我们自己来进行构造。本文就是把单层网络里面最简单的随机网络构造在多层网络的层内。主要是用来python里面的networkx库,下面给出代码。
# -*- coding: utf-8 -*-
"""
Created on Fri Jun 14 21:01:29 2019
@author: Administrator
"""
"""
随机网络是由一些节点通过随机连接而组成的一种复杂网络。
随机网络有两种等价方法
(1).ER模型:给定N个节点,最多可以存在N(N-1)/2条边,
从这些边中随机选择M条边就可以得到一个随机网络,
且每一种可能的概率相同
(2).二项式模型:给定N个节点,每一对节点以概率p进行连接,
这样,所有连线的数目是一个随机变量,其平均值为
M = pN(N-1)/2
"""
"""
层内节点连接的算法思想介绍:
此算法就是为了模拟随机网络里面的二项式模型
每一次每个在给定的节点总数nodes之间的任意两个节点都有连接的可能
即要模拟到随机网络的随机性。在给定的概率为p的情况之下,
即每两个节点之间连接的概率为p,nodes个节点之间的连边数目是一个随机变量,
平均值为 M = pN(N-1)/2
"""
"""
层间邻接矩阵产生的算法思想介绍:由于每一层内的标号都是1.2....n,
所以当上下两层进行连接的时候,会产生上层的1和下层的1进行连接的这种情况。
在构造邻接矩阵的时候会出现情况,所以在对邻接矩阵进行存储的时候,
每一层的下标会进行改变,比如第一层的还是为1,2,3....n
但是第二层的时候,1号下标会进行改变,改变的规则为每一层的下标会对前面所有层的下标进行累计
比如:第二层的1号为,(第二层的1号下标) = 1 + (2 - 1)*len(layer_nodes),
其中2为第2层层数,1为第1层层数。layer_nodes为每一层的节点数目,
当每一层有4个节点的时候,(第二层的1号下标) = 5 。
"""
"""
整个网络的邻接矩阵构造思想介绍:
还是仿照单层的思想,两个节点之间有边则为1,没有边则为0,
比如一个多层网络存在三层的话,则第一层和第二层存在边的话,
则为1,不存在边的话,则为0.但是第一层和第三层之间肯定是
不存在连边的,所以全部为0.分别为整个网络添加层内和层间的连边,
即可以完成整个多层邻接矩阵的构造
"""
import networkx as nx
import random
import matplotlib.pyplot as plt
import numpy as np
#node_number为节点总数,layer_number为层数
#p为层间的连接概率
def ER_ER_MultilayerNetwork(node_number,layer_number,p,G):
#用来存储层间的邻接矩阵
filename = "test.txt"
#用来存储整个网络的邻接矩阵
filename1 = "test2.txt"
#用来存储层间的邻接矩阵
filename2 = "test3.txt"
with open(filename,"w") as files:
files.truncate()
with open(filename1,"w") as file1s:
file1s.truncate()
with open(filename2,"w") as file2s:
file2s.truncate()
#全部输出
np.set_printoptions(suppress=True, threshold=1e10)
#添加每一层的节点
nodes = list(range(1,node_number+1))
#添加层数
layers = list(range(1,layer_number+1))
#用来存储整个多层网络的边
edges2_list = []
#产生一个空图,来存储整个网络所有的节点。从而产生整个网络的邻接矩阵
G2 = nx.Graph()
G2.add_nodes_from(list(range(1,node_number*layer_number + 1)))
#print(list(range(1,node_number*layer_number + 1)))
#根据算法思想来添加层内的边数
for layer in layers:
print("第"+str(layer)+"层层内的邻接矩阵为:")
print(nx.to_numpy_matrix(G))
with open(filename2,"a") as file2:
file2.write("第"+str(layer)+"层层内的邻接矩阵为:\n")
file2.write(str(nx.to_numpy_matrix(G)) + "\n")
#根据算法思想来添加层间的边数
for layer in layers:
#用来存储每一个图的边
edges_list = []
#产生一个空图,来存储层间的图,从而产生邻接矩阵
G1 = nx.Graph()
G1.add_nodes_from(list(range(1,node_number * 2 + 1)))
length = len(nodes)
#nodes个节点之间连边的数目
m = int(p*length*(length - 1)/2)
values = list(range(1,m+1))
for value in values:
#这个循环是用来去掉层内的自环和重边
while(True):
count = 0
#层内连接的第一个节点
first = random.randint(1,length)
# print("first:" + str(first))
#这个循环用来解决自环问题
while(True):
#层内连接的第二个节点
last = random.randint(1,length)
if(last != first):
# print("last:" + str(last))
break
#这个循环用来去掉重边
for edges in edges_list:
if((first == edges[0] and last == edges[1]) or
(first == edges[1] and last == edges[0])):
break
else:
count = count + 1
# print(count)
if(count == len(edges_list)):
break
edge = (first,last)
edges_list.append(edge)
if layer < layer_number:
G1.add_edge(first,last + node_number)
edge2 = (first + node_number * (layer - 1), last + node_number * layer )
edges2_list.append(edge2)
G2.add_edges_from(edges2_list)
if(layer < layer_number):
with open(filename,"a") as file1:
str1 = str(layer) + "和" + str(layer + 1) + "层之间的邻接矩阵为:\n"
print(str1)
file1.write(str1)
print(nx.to_numpy_matrix(G1))
file1.write(str(nx.to_numpy_matrix(G1)) + "\n")
print("整个网络的邻接矩阵如下:")
print(nx.to_numpy_matrix(G2))
with open(filename1,"a") as file3:
file3.write("整个网络的邻接矩阵如下:\n")
file3.write(str(nx.to_numpy_matrix(G2)) + "\n")
def network():
#随机网络
#G = nx.erdos_renyi_graph(200,0.8)
#小世界网络
#G = nx.watts_strogatz_graph(200, 4, 0.8)
#BA网络
G = nx.barabasi_albert_graph(200,8)
ER_ER_MultilayerNetwork(200,3,0.9,G)
network()
由于使用的是对邻接矩阵进行拼接的方式,所以整个网络的邻接矩阵并不是完整的,需要把相应部分的邻接矩阵添加进去。这里只是给出了随机网络构造在层内的构造思想。