复杂网络科学是一门跨学科领域,研究各种网络结构和它们上的信息、现象传播。点渗流和边渗流是复杂网络科学中两种常见的渗流现象,它们用于描述信息、疾病、谣言等在网络中的传播过程。
点渗流(Node Percolation):
点渗流是一种模拟网络节点的随机移除或失活的过程。这个过程类似于在网络中随机去掉一些节点,然后观察网络的连通性如何变化。点渗流通常用于研究网络的鲁棒性和稳定性。当节点被移除后,原本联通的网络可能分裂成多个子网络,这有助于研究网络中哪些节点是关键节点,其移除会对网络的连通性产生最大影响。点渗流还可以用来模拟网络中信息传播的弱化,例如社交网络中个体的退出或信息源的移除。
边渗流(Edge Percolation):
边渗流是一种模拟随机移除或失活网络边的过程。在边渗流中,网络的节点保持不变,但是网络中的连接被断开。这可以模拟网络中连接的可靠性或稳定性。边渗流通常用于研究网络的鲁棒性和抗攻击性。移除网络中的边可以模拟网络中的通信线路中断或互联网链路故障,以帮助研究者了解网络在面对外部攻击或故障时的表现。
点渗流和边渗流是复杂网络科学中用于研究网络结构的重要工具。它们有助于揭示网络中的脆弱性,识别关键节点或边,以及理解信息和现象在网络中的传播方式。这些研究有助于改进网络设计、优化资源分配、预测疾病传播趋势,以及改进网络的鲁棒性。
作为入门复杂网络的渗流经典结果代码,ER网络的点渗流和边,参考《网络渗流》P83。
代码如下:
import random
import time
import numpy as np
import matplotlib.pyplot as plt
import networkx as nx
from scipy.optimize import fsolve
plt.rcParams['font.sans-serif'] = ['SimHei']
# 节点数
n = 2 ** 12
# 平均度
k = 4
def attackNetwork(G, p):
"""
点渗流
:param G:初始图
:param p:保留概率
:return:
"""
G1 = G.copy()
nodes = G1.nodes()
for i in range(len(nodes)):
# 当节点存在删除节点
if random.random() > p and G1.has_node(i):
G1.remove_node(i)
return G1
def attackNetwork1(G, p):
"""
边渗流
:param G:
:param p:
:return:
"""
G2 = nx.Graph()
nodes = G.nodes()
# 复制初始图的节点
for node in nodes:
G2.add_node(node)
edges = G.edges()
for (u, v) in edges:
# 以p的概率保留边
if random.random() <= p:
G2.add_edge(u, v)
return G2
def calculateS(G, G1):
"""
计算巨分支大小S
:param G:初始网络
:param G1:被攻击后的网络
:return:S大小
"""
if len(G1.nodes) == 0:
return 0
largest_cc = max(nx.connected_components(G1), key=len)
return len(largest_cc) / len(G.nodes)
# 点渗流
def getS1(p):
"""
点渗流理论解
:param p:节点保留概率
:return:极大连通子图大小
"""
def func(S, p):
return p * (1 - np.exp(-k * S)) - S
S = 0
initialGuesses = [val for val in np.linspace(0, 1, 10)]
for initialGuess in initialGuesses:
root, data, ier, msg = fsolve(func, initialGuess, args=(p), full_output=True)
if ier == 1:
S = root
return S
# 边渗流
def getS(p):
"""
边渗流理论解
:param p:边保留概率
:return:极大连通子图大小
"""
def func(S, p):
return 1 - np.exp(-p * k * S) - S
S = 0
initialGuesses = [val for val in np.linspace(0, 1, 10)]
for initialGuess in initialGuesses:
root, data, ier, msg = fsolve(func, initialGuess, args=(p), full_output=True)
if ier == 1:
S = root
return S
getS = np.vectorize(getS)
getS1 = np.vectorize(getS1)
X = np.linspace(0, 1, 20)
start = time.time()
G = nx.erdos_renyi_graph(n, k / n)
# S 点渗流模拟
S = []
for p in X:
G1 = attackNetwork(G, p)
S.append(calculateS(G, G1))
# S1 边渗流模拟
S1 = []
for p in X:
G2 = attackNetwork1(G, p)
S1.append(calculateS(G, G2))
print(S)
print(S1)
p = np.linspace(0, 1, 100)
# 绘图
plt.figure
plt.scatter(X, S, c='g')
plt.scatter(X, S1)
plt.plot(p, getS(p), "k-.",)
plt.plot(p, getS1(p), "k-",)
plt.legend(loc='upper left', labels=['边渗流', '点渗流'])
plt.show()
end = time.time()
print("Time:", end - start)