在网络科学里面有单层的小世界网络,随机网络和无标度网络,在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()

由于使用的是对邻接矩阵进行拼接的方式,所以整个网络的邻接矩阵并不是完整的,需要把相应部分的邻接矩阵添加进去。这里只是给出了随机网络构造在层内的构造思想。