本文目录导读:

我来为您介绍如何使用NetworkX进行网络演化分析,包含多个实用案例。
基础网络演化模型
1 随机网络演化(ER模型)
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.animation import FuncAnimation
# 随机图演化过程
def random_graph_evolution(n_initial=5, n_max=50, p=0.1):
"""
模拟随机图的演化过程
"""
graphs = []
G = nx.Graph()
# 初始图
G.add_nodes_from(range(n_initial))
for i in range(n_initial):
for j in range(i+1, n_initial):
if np.random.random() < p:
G.add_edge(i, j)
graphs.append(G.copy())
# 逐步添加新节点
for t in range(n_initial, n_max):
G.add_node(t)
# 新节点与现有节点随机连接
for i in range(t):
if np.random.random() < p:
G.add_edge(t, i)
graphs.append(G.copy())
return graphs
# 可视化演化过程
def visualize_evolution(graphs, interval=200):
"""
动态显示网络演化
"""
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
def update(frame):
axes[0].clear()
axes[1].clear()
G = graphs[frame]
# 网络结构图
pos = nx.spring_layout(G, k=2, iterations=50)
nx.draw(G, pos, ax=axes[0],
node_color='lightblue',
node_size=200,
edge_color='gray',
with_labels=True)
axes[0].set_title(f'时间步 {frame}: {len(G.nodes)} 节点, {len(G.edges)} 边')
# 度分布
degrees = [d for n, d in G.degree()]
axes[1].hist(degrees, bins=range(min(degrees), max(degrees)+2),
alpha=0.7, color='skyblue', edgecolor='black')
axes[1].set_xlabel('度')
axes[1].set_ylabel('频率')
axes[1].set_title('度分布')
plt.tight_layout()
ani = FuncAnimation(fig, update, frames=len(graphs),
interval=interval, repeat=False)
plt.show()
return ani
# 运行示例
graphs = random_graph_evolution(n_initial=3, n_max=20, p=0.15)
visualize_evolution(graphs)
2 BA无标度网络演化
def ba_scale_free_evolution(n_initial=3, n_max=100, m=2):
"""
Barabási-Albert 无标度网络演化
"""
graphs = []
# 初始完全图
G = nx.complete_graph(n_initial)
graphs.append(G.copy())
# 使用BA模型添加节点
for t in range(n_initial, n_max):
G.add_node(t)
# 优先连接:新节点更倾向于连接度高的节点
targets = []
for _ in range(min(m, len(G.nodes)-1)):
degrees = np.array([d for n, d in G.degree()])
probs = degrees / degrees.sum()
# 避免重复连接
available = [n for n in G.nodes() if n != t and n not in targets]
if len(available) > 0:
probs_available = np.array([G.degree(n) for n in available])
probs_available = probs_available / probs_available.sum()
target = np.random.choice(available, p=probs_available)
G.add_edge(t, target)
targets.append(target)
graphs.append(G.copy())
return graphs
# 分析BA网络特性
def analyze_network_properties(G):
"""
分析网络的各种统计特性
"""
properties = {}
# 基本统计
properties['节点数'] = len(G.nodes())
properties['边数'] = len(G.edges())
properties['平均度'] = np.mean([d for n, d in G.degree()])
# 连通性分析
if nx.is_connected(G):
properties['平均路径长度'] = nx.average_shortest_path_length(G)
else:
components = list(nx.connected_components(G))
properties['连通分量数'] = len(components)
properties['最大分量比例'] = len(max(components, key=len)) / len(G.nodes())
# 聚类系数
properties['平均聚类系数'] = nx.average_clustering(G)
# 度分布幂律拟合
degrees = [d for n, d in G.degree()]
properties['最大度'] = max(degrees)
properties['度分布偏度'] = np.mean(degrees) / np.median(degrees) if degrees else 0
return properties
# 运行并分析
graphs = ba_scale_free_evolution(n_initial=5, n_max=50, m=2)
final_graph = graphs[-1]
props = analyze_network_properties(final_graph)
print("BA网络特性分析:")
for key, value in props.items():
print(f"{key}: {value:.3f}")
动态网络演化模型
1 边演化模型
def edge_dynamics_evolution(n_nodes=20, p_add=0.05, p_remove=0.02, t_max=50):
"""
边的动态添加和移除演化
"""
graphs = []
# 初始化随机图
G = nx.erdos_renyi_graph(n_nodes, 0.1)
graphs.append(G.copy())
for t in range(t_max):
# 随机添加边
for i in range(n_nodes):
for j in range(i+1, n_nodes):
if not G.has_edge(i, j) and np.random.random() < p_add:
G.add_edge(i, j)
# 随机移除边
edges_to_remove = []
for edge in G.edges():
if np.random.random() < p_remove:
edges_to_remove.append(edge)
G.remove_edges_from(edges_to_remove)
graphs.append(G.copy())
return graphs
# 可视化边演化
def plot_edge_evolution(graphs):
"""
绘制边数随时间的演化
"""
edge_counts = [len(G.edges()) for G in graphs]
node_counts = [len(G.nodes()) for G in graphs]
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
# 边数变化
axes[0].plot(edge_counts, 'b-', linewidth=2)
axes[0].set_xlabel('时间步')
axes[0].set_ylabel('边数')
axes[0].set_title('网络边数演化')
axes[0].grid(True, alpha=0.3)
# 密度变化
densities = [2*e/(n*(n-1)) if n > 1 else 0
for n, e in zip(node_counts, edge_counts)]
axes[1].plot(densities, 'r-', linewidth=2)
axes[1].set_xlabel('时间步')
axes[1].set_ylabel('网络密度')
axes[1].set_title('网络密度演化')
axes[1].grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# 运行示例
graphs = edge_dynamics_evolution(n_nodes=30, p_add=0.03, p_remove=0.01, t_max=30)
plot_edge_evolution(graphs)
2 节点和边同时演化
def complete_network_evolution(n_initial=5, n_max=30,
p_add_edge=0.1, p_remove_edge=0.05,
p_add_node=0.2, p_remove_node=0.05):
"""
完整的网络演化:节点和边同时变化
"""
graphs = []
G = nx.complete_graph(n_initial)
graphs.append(G.copy())
current_id = n_initial
for t in range(50): # 最多50个时间步
if len(G.nodes()) >= n_max:
break
# 添加新节点
if np.random.random() < p_add_node and len(G.nodes()) < n_max:
G.add_node(current_id)
# 新节点连接策略:优先连接
if len(G.nodes()) > 1:
degrees = np.array([d for n, d in G.degree() if n != current_id])
if degrees.sum() > 0:
probs = degrees / degrees.sum()
nodes = [n for n in G.nodes() if n != current_id]
# 连接2-3个节点
n_connections = min(np.random.randint(2, 4), len(nodes))
targets = np.random.choice(nodes, size=n_connections,
p=probs, replace=False)
for target in targets:
G.add_edge(current_id, target)
current_id += 1
# 移除节点
if np.random.random() < p_remove_node and len(G.nodes()) > n_initial:
node_to_remove = np.random.choice(list(G.nodes()))
G.remove_node(node_to_remove)
# 边演化
all_nodes = list(G.nodes())
for i in range(len(all_nodes)):
for j in range(i+1, len(all_nodes)):
if np.random.random() < p_add_edge and not G.has_edge(all_nodes[i], all_nodes[j]):
G.add_edge(all_nodes[i], all_nodes[j])
elif np.random.random() < p_remove_edge and G.has_edge(all_nodes[i], all_nodes[j]):
G.remove_edge(all_nodes[i], all_nodes[j])
graphs.append(G.copy())
return graphs
网络演化统计与可视化
1 演化指标追踪
def track_evolution_metrics(graphs):
"""
追踪网络演化的多种指标
"""
metrics = {
'time': [],
'nodes': [],
'edges': [],
'density': [],
'avg_degree': [],
'clustering': [],
'connectivity': []
}
for t, G in enumerate(graphs):
metrics['time'].append(t)
metrics['nodes'].append(len(G.nodes()))
metrics['edges'].append(len(G.edges()))
n = len(G.nodes())
metrics['density'].append(2*len(G.edges())/(n*(n-1)) if n > 1 else 0)
degrees = [d for n, d in G.degree()]
metrics['avg_degree'].append(np.mean(degrees) if degrees else 0)
metrics['clustering'].append(nx.average_clustering(G))
metrics['connectivity'].append(nx.is_connected(G))
return metrics
def plot_evolution_metrics(metrics):
"""
绘制多个演化指标
"""
fig, axes = plt.subplots(2, 3, figsize=(15, 10))
plot_configs = [
(0, 0, 'nodes', '节点数', 'b-'),
(0, 1, 'edges', '边数', 'g-'),
(0, 2, 'density', '网络密度', 'r-'),
(1, 0, 'avg_degree', '平均度', 'c-'),
(1, 1, 'clustering', '聚类系数', 'm-'),
(1, 2, 'connectivity', '连通性', 'y-')
]
for row, col, key, title, style in plot_configs:
axes[row, col].plot(metrics['time'], metrics[key], style, linewidth=2)
axes[row, col].set_xlabel('时间步')
axes[row, col].set_ylabel(title)
axes[row, col].set_title(f'{title}演化')
axes[row, col].grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# 运行完整的演化分析
print("开始网络演化分析...")
graphs = complete_network_evolution(n_initial=4, n_max=25)
metrics = track_evolution_metrics(graphs)
plot_evolution_metrics(metrics)
2 网络演化模拟器类
class NetworkEvolutionSimulator:
"""
网络演化模拟器类
"""
def __init__(self, initial_nodes=5):
self.graph = nx.Graph()
self.graph.add_nodes_from(range(initial_nodes))
self.history = [self.graph.copy()]
self.current_id = initial_nodes
def add_random_node(self, m=2):
"""添加新节点(优先连接)"""
n = len(self.graph.nodes())
self.graph.add_node(self.current_id)
if n > 0:
# 优先连接
degrees = np.array([d for n, d in self.graph.degree() if n != self.current_id])
if degrees.sum() > 0:
probs = degrees / degrees.sum()
nodes = [n for n in self.graph.nodes() if n != self.current_id]
n_connections = min(m, len(nodes))
if n_connections > 0:
targets = np.random.choice(nodes, size=n_connections,
p=probs, replace=False)
for target in targets:
self.graph.add_edge(self.current_id, target)
self.current_id += 1
self.history.append(self.graph.copy())
def remove_random_node(self):
"""随机移除节点"""
if len(self.graph.nodes()) > 3: # 保留至少3个节点
node = np.random.choice(list(self.graph.nodes()))
self.graph.remove_node(node)
self.history.append(self.graph.copy())
def add_random_edges(self, prob=0.1):
"""随机添加边"""
nodes = list(self.graph.nodes())
for i in range(len(nodes)):
for j in range(i+1, len(nodes)):
if not self.graph.has_edge(nodes[i], nodes[j]):
if np.random.random() < prob:
self.graph.add_edge(nodes[i], nodes[j])
self.history.append(self.graph.copy())
def rewire_edges(self, prob=0.05):
"""重连边"""
edges = list(self.graph.edges())
for u, v in edges:
if np.random.random() < prob:
# 随机选择一个新端点
nodes = [n for n in self.graph.nodes() if n not in [u, v]]
if nodes:
new_v = np.random.choice(nodes)
if not self.graph.has_edge(u, new_v):
self.graph.remove_edge(u, v)
self.graph.add_edge(u, new_v)
self.history.append(self.graph.copy())
def get_summary(self):
"""获取当前网络摘要"""
G = self.graph
summary = {
'nodes': len(G.nodes()),
'edges': len(G.edges()),
'density': nx.density(G),
'avg_degree': np.mean([d for n, d in G.degree()]),
'clustering': nx.average_clustering(G),
'is_connected': nx.is_connected(G)
}
return summary
def simulate_evolution(self, n_steps=20):
"""运行演化模拟"""
for step in range(n_steps):
action = np.random.choice(['add_node', 'remove_node',
'add_edges', 'rewire'],
p=[0.4, 0.1, 0.3, 0.2])
if action == 'add_node':
self.add_random_node(m=np.random.randint(1, 4))
elif action == 'remove_node' and len(self.graph.nodes()) > 5:
self.remove_random_node()
elif action == 'add_edges':
self.add_random_edges(prob=np.random.uniform(0.05, 0.15))
elif action == 'rewire':
self.rewire_edges(prob=np.random.uniform(0.05, 0.15))
return self.history
# 使用模拟器
sim = NetworkEvolutionSimulator(initial_nodes=5)
history = sim.simulate_evolution(n_steps=30)
# 分析结果
metrics = track_evolution_metrics(history)
plot_evolution_metrics(metrics)
print("最终网络摘要:")
summary = sim.get_summary()
for key, value in summary.items():
print(f"{key}: {value:.3f}")
实际应用案例
1 社交网络演化
def social_network_evolution(n_users=50, n_steps=100):
"""
模拟社交网络的演化
"""
G = nx.Graph()
# 初始化用户
G.add_nodes_from(range(n_users))
# 用户属性
for node in G.nodes():
G.nodes[node]['age'] = np.random.randint(18, 60)
G.nodes[node]['interests'] = set(np.random.choice(
['sports', 'music', 'tech', 'art', 'travel', 'food'],
size=np.random.randint(1, 4), replace=False))
history = [G.copy()]
for step in range(n_steps):
# 基于共同兴趣添加边
for i in range(n_users):
for j in range(i+1, n_users):
if not G.has_edge(i, j):
common_interests = len(G.nodes[i]['interests'] & G.nodes[j]['interests'])
age_diff = abs(G.nodes[i]['age'] - G.nodes[j]['age'])
# 连接概率:共同兴趣越多,年龄越接近,概率越大
prob = (common_interests * 0.1 + (1 - age_diff/60) * 0.05)
if np.random.random() < prob:
G.add_edge(i, j)
# 基于弱关系断开边
edges_to_remove = []
for u, v in G.edges():
if len(G.nodes[u]['interests'] & G.nodes[v]['interests']) == 0:
if np.random.random() < 0.1:
edges_to_remove.append((u, v))
G.remove_edges_from(edges_to_remove)
history.append(G.copy())
return history
# 运行社交网络演化
social_history = social_network_evolution(n_users=30, n_steps=20)
print(f"社交网络演化:从{social_history[0].number_of_nodes()}节点到"
f"{social_history[-1].number_of_nodes()}节点")
这些案例展示了NetworkX在网络演化分析中的强大功能,包括:
- 多种演化模型的实现
- 动态可视化
- 网络拓扑指标分析
- 实际应用场景模拟
您可以根据具体需求调整参数和模型,应用到不同的网络演化研究场景中。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播