通过SIR模型来验证复杂网络影响力最大化

不穿秋裤的南方人    2019-05-27 09:42

毕业设计的后一个部分是挖掘网络中的关键节点组,基于目前国内外所发表的相关论文,整合并结合自身的需要,现提供如下参考代码,希望给予相关意见。

目前,主要验证节点组选取的好坏是通过传染病模型进行仿真实验,通过给定传染率、恢复率,以及关键节点组(也就是种子),查看传染病传染达到稳定状态时,整个网络中R型节点的占比。

代码初版如下所示:

import networkx as nx
import random
import matplotlib.pyplot as plt


def sir_one(graph, seeds, beta=0.4, mu=0.1):
    """单接触SIR模型
    传染率beta;恢复率mu"""
    I_set = set(seeds)
    S_set = set(graph.nodes()).difference(I_set)
    R_set = set()

    t = 0

    while len(I_set) > 0:
        Ibase = I_set.copy()
        for i in Ibase:
            # I --> R
            if random.random() < mu:
                I_set.remove(i)
                R_set.add(i)

            # S --> I
            if random.random() < beta:
                tmp = list(set(graph.neighbors(i)).intersection(S_set).copy())
                if len(tmp) > 0:
                    s = random.choice(tmp)
                    S_set.remove(s)
                    I_set.add(s)

        t += 1

    per_R = len(R_set) / len(graph.nodes())
    # print(t)
    # print("The percentage of R: " + str(per_R))

    return per_R


def sir_more(graph, seeds, beta=0.4, mu=1):
    """全接触SIR模型
    传染率beta;恢复率mu"""
    I_set = set(seeds)
    S_set = set(graph.nodes()).difference(I_set)
    R_set = set()

    t = 0

    while len(I_set) > 0:
        Ibase = I_set.copy()
        for i in Ibase:
            # I --> R
            if random.random() < mu:
                I_set.remove(i)
                R_set.add(i)

            # S --> I
            tmp = list(set(graph.neighbors(i)).intersection(S_set).copy())
            for s in tmp:
                if random.random() < beta:
                    S_set.remove(s)
                    I_set.add(s)

        t += 1

    per_R = len(R_set) / len(graph.nodes())
    # print(t)
    # print("The percentage of R: " + str(per_R))

    return per_R


def centrality_index(graph, num):
    """复杂网络中心性指标"""
    # degree
    degree_graph = dict(nx.degree(graph))
    trans_degree = list(zip(degree_graph.values(), degree_graph.keys()))
    trans_degree.sort(reverse=True)
    # print(trans_degree)
    degree_seed = []
    for i in range(num):
        degree_seed.append(trans_degree[i][1])

    # core
    core_graph = dict(nx.core_number(graph))
    trans_core = list(zip(core_graph.values(), core_graph.keys()))
    trans_core.sort(reverse=True)
    # print(trans_core)
    core_seed = []
    for i in range(num):
        core_seed.append(trans_core[i][1])

    # betweenness
    betweenness_graph = nx.betweenness_centrality(graph)
    trans_betweenness = list(zip(betweenness_graph.values(), betweenness_graph.keys()))
    trans_betweenness.sort(reverse=True)
    # print(trans_betweenness)
    betweenness_seed = []
    for i in range(num):
        betweenness_seed.append(trans_betweenness[i][1])

    return degree_seed, core_seed, betweenness_seed


def count_r(graph, index):
    """传染病模型仿真达到稳定状态下R占整个网络的比例"""
    res_one = []
    res_more = []
    for a in range(1000):
        res_one.append(sir_one(graph, index))
        res_more.append(sir_more(graph, index))
    print("单接触SIR", sum(res_one) / len(res_one))
    print("全接触SIR", sum(res_more) / len(res_more))
    print("-----------------")


if __name__ == '__main__':
    G = nx.read_edgelist(r"E:\NE_DATA\email\email-Eu-core.edgelist")
    # nx.draw_networkx(graph)
    # plt.show()

    degrees, cores, betweennesses = centrality_index(G, 5)

    print("Degree Top 5: ", degrees)
    count_r(G, degrees)

    print("Core Top 5: ", cores)
    count_r(G, cores)

    print("Betweenness Top 5: ", betweennesses)
    count_r(G, betweennesses)

    nes = ['659', '928', '385', '713', '500']
    print("NE Top 5: ", nes)
    count_r(G, nes)

后通过查看论文,和进行对比分析,改进了第一版本的代码。第一版的代码中,每个I态节点尝试去感染邻居中S态的节点;而真实的定义中,每个I态节点尝试去感染邻居,并没有要求必须是S态节点。由第一版代码会导致在后续的对比分析实验中,无法去验证某种方法在接触有效性方面的效果,故而修改了第一版代码,如下所示。

# 每个I态节点尝试去感染其邻居节点,如果被感染节点为S态节点,即为有效接触,否则是无效接触
def sir_one(graph, seeds, beta=0.35, mu=0.1):
    """单接触SIR模型
    传染率beta;恢复率mu"""
    I_set = set(seeds)
    S_set = set(graph.nodes()).difference(I_set)
    R_set = set()

    t = 0

    while len(I_set) > 0:
        Ibase = I_set.copy()
        for i in Ibase:
            # I --> R
            if random.random() < mu:
                I_set.remove(i)
                R_set.add(i)

            # S --> I
            tmp = list(graph.neighbors(i))
            s = random.choice(tmp)
            if random.random() < beta:
                if s in S_set:
                    S_set.remove(s)
                    I_set.add(s)

        t += 1

    return len(R_set)


def sir_more(graph, seeds, beta=0.35, mu=1):
    """全接触SIR模型
    传染率beta;恢复率mu"""
    I_set = set(seeds)
    S_set = set(graph.nodes()).difference(I_set)
    R_set = set()

    t = 0

    while len(I_set) > 0:
        Ibase = I_set.copy()
        for i in Ibase:
            # I --> R
            if random.random() < mu:
                I_set.remove(i)
                R_set.add(i)

            # S --> I
            tmp = list(graph.neighbors(i))
            for s in tmp:
                if random.random() < beta:
                    if s in S_set:
                        S_set.remove(s)
                        I_set.add(s)

        t += 1

    return len(R_set)

 

Views: 4.0K

[[total]] comments

Post your comment
  1. [[item.time]]
    [[item.user.username]] [[item.floor]]Floor
  2. Click to load more...
  3. Post your comment