常见网络模型——ER随机图、规则图、BA、WS小世界
ER随机图:(没有重边和自环的简单图)
定义一:具有固定边数的ER随机图 G(N,M)
构造算法:
(1)初始化:给定 N 个节点和待添加的边数 M
(2)随机连边:
- 随机选取一对没有边相连的不同节点,并在这对节点之间添加一条边
- 重复步骤1,直到在 M 对不同节点对之间各添加了一条边
定义二:具有固定连边概率的ER随机图 G(N,p)
构造算法:
(1)初始化:给定 N 个节点以及连边概率 p∈[0,1]
(2)随机连边:
- 选择一对没有边相连的不同节点
- 生成一个随机数 r ∈(0,1)
- 如果 r < p,那么在这对节点之间添加一条边;否则就不添加边
- 重复步骤1、2、3,直到所有节点对都被选择过一次
不使用已有库函数,自己编写模型如下:
import networkx as nx
import numpy as np
'''ER model :generate a ER graph'''
def ERmodel(NodeNum, ER_P):
Node_num = NodeNum
N = list(range(Node_num))
G_ER = nx.Graph()
G_ER.add_nodes_from(N)
p = ER_P
AdjMatrix = np.random.randint(0, 10, (Node_num, Node_num))
# ER 无权无向
AdjMatrix[0][0] = 0
for i in range(1, Node_num):
AdjMatrix[i][i] = 0
for j in range(i):
if i > j and AdjMatrix[i][j] < p:
G_ER.add_edge(i, j)
AdjMatrix[i][j] = 1
AdjMatrix[j][i] = 1
else:
AdjMatrix[i][j] = 0
AdjMatrix[j][i] = 0
规则图之最近邻耦合网络:具有周期边界条件,每个节点与最近邻 2k 个点连线
import networkx as nx
if __name__ == '__main__':
NUM1 = 500
K = 15 # 最近邻 2K 个点连线
K1 = K + 1
g = nx.Graph()
N = list(range(NUM1))
g.add_nodes_from(N) # 增加 NUM1 个点
for i in range(NUM1):
for j in range(1, K1):
K_add = NUM1 - K
i_add_j = i + j + 1
if i >= K_add and i_add_j > NUM1: # 大数标签节点 加数邻边 加边判断
i_add = i + j - NUM1
g.add_edge(i, i_add)
else:
i_add = i + j
g.add_edge(i, i_add)
BA无标度网络:
考虑网络的增长特性和优先连接(好像更多的人使用轮盘赌算法,以后再加好了)
增长特性:网络的规模是不断扩大的
优先连接:新的节点更倾向于与那些具有较高连接度的 hub 节点连接
构造算法:
(1)增长:从一个具有 m0 个节点的连通网络开始,每次引入一个新的节点并且连到 m 个已存在的节点上,这里 m≤m0
(2)优先连接:一个新节点与一个已经存在的节点 i 相连接的概率 P_i 与节点 i 的度 k_i 之间满足关系:
P_i = k_i / ∑k_j
import networkx as nx
import numpy as np
import random
import math
if __name__ == '__main__':
m_0 = 4
m = 2
t = 496
NUM = m_0 + t
g = nx.Graph()
N = list(range(m_0))
g.add_nodes_from(N)
k = [] # 保存各节点的度
k_0 = m_0-1
p_k = [] # 保存各节点的优先概率
p_0 = 1/m_0
k_all = 0
for i in range(m_0): # 初始的完全图
p_k.append(p_0)
k.append(k_0)
k_all += k_0
for j in range(i,m_0):
g.add_edge(i,j)
for i in range(t):
m_0_t = m_0 + i # t 时刻的节点数
m_0_1 = m_0 + i - 1 # t-1 时刻的节点数
g.add_node(m_0_t)
# k_all = 0
# for j in range(m_0_t_1):
# k_all += k[j]
add_edge = 1
while(add_edge<=m):
for j in range(m_0_1): # 按照节点顺序比较,人为使得标签小的节点度偏大
p_random = random.random() # 是否应该从概率最大的开始比较
if p_random <= p_k[j] and add_edge <= m:
k_j = k[j]
p_k_j = p_k[j]
g.add_edge(m_0_t,j)
add_edge += 1
k[j] = k_j + 1
k_all += 2 # 增加一条边,度增加 2
p_k[j] = (k_j + 1)/k_all
k.append(2)
p = 2/k_all
p_k.append(p)
WS小世界模型:
作为从完全规则网络向完全随机网络的过渡,在规则网络中引入少许的随机性
构造算法:
(1)从规则图开始:给定一个含有 N 个点的环状最近邻耦合网络,其中每个节点都与它左右相邻的各 K/2 个节点相连,K是偶数;
(2)随机化重连:以概率 p 随机地重新连接网络中原有的每条边,即把每条边的一个端点保持不变,另一个端点改取为网络中随机选择的一个节点,其中规定不得有重边和自环
(在上述模型中,p=0 对应于完全规则网络,p=1 对应于完全随机网络)
在具体算法实现时,可以把网络中所有节点编号为 1, 2, ..., N ;对于每个节点 i,顺时针选取与节点 i 相连的 K/2 条边中的每一条边,边的一个端点仍然固定为节点 i, 以概率 p 随机选取网络中的任一个节点作为该条边的另一个端点。因此,严格来说,即使在 p=1 的情况下,通过这种算法得到的WS小世界模型与相同节点,相同变数的ER随机图模型还是有区别的:毕竟,在WS小世界中每个节点的度至少是 K/2, 而在ER随机图中则无此限制
import networkx as nx
import numpy as np
import random
if __name__ == '__main__':
NUM1 = 500
NUM2 = NUM1 - 1
K = 15 # 最近邻 2K 个点连线
K1 = K + 1
p = 0.3
g = nx.Graph()
N = list(range(NUM1))
g.add_nodes_from(N) # 增加 N 个点
for i in range(NUM1):
for j in range(1, K1):
K_add = NUM1 - K
i_add_j = i + j + 1
if i >= K_add and i_add_j > NUM1: # 大数标签节点 加数邻边 加边判断
i_add = i + j - NUM1
g.add_edge(i, i_add)
else:
i_add = i + j
g.add_edge(i, i_add)
# 按照概率 p = 0.3 重连
for i in range(NUM1):
for e_del in range(i + 1, i + K1):
if e_del >= NUM1: # 找到的节点标签大于实际中的标签,标签更正
e_del = e_del - NUM1
P_random = random.randint(0, 9)
if P_random <= 2:
g.remove_edge(i, e_del)
e_add = random.randint(0, NUM2) # 0 - NUM2 都可能
while e_add == i or g.has_edge(i, e_add) == True:
e_add = random.randint(0, NUM2)
g.add_edge(i, e_add)
更多推荐
所有评论(0)