ER随机图:(没有重边和自环的简单图)

定义一:具有固定边数的ER随机图 G(N,M)

构造算法:

(1)初始化:给定 N 个节点和待添加的边数 M

(2)随机连边:

  1. 随机选取一对没有边相连的不同节点,并在这对节点之间添加一条边
  2. 重复步骤1,直到在 M 对不同节点对之间各添加了一条边

定义二:具有固定连边概率的ER随机图 G(N,p)

构造算法:

(1)初始化:给定 N 个节点以及连边概率 p∈[0,1]

(2)随机连边:

  1. 选择一对没有边相连的不同节点
  2. 生成一个随机数 r ∈(0,1)
  3. 如果 r < p,那么在这对节点之间添加一条边;否则就不添加边
  4. 重复步骤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)

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐