本文目录导读:

我来介绍使用NetworkX进行网络压缩的几种常用方法:
基于度的节点筛选
import networkx as nx
import matplotlib.pyplot as plt
import random
# 创建示例图
G = nx.barabasi_albert_graph(100, 2) # 无标度网络
# 方法1:按节点度筛选
def compress_by_degree(G, threshold=5):
"""保留度大于阈值的节点"""
nodes_to_keep = [n for n, d in G.degree() if d > threshold]
G_compressed = G.subgraph(nodes_to_keep).copy()
return G_compressed
G_degree = compress_by_degree(G, threshold=10)
print(f"原始节点数: {G.number_of_nodes()}, 压缩后: {G_degree.number_of_nodes()}")
社区检测压缩
# 方法2:基于社区检测进行压缩
def compress_by_community(G, method='louvain'):
"""使用社区检测合并节点"""
try:
import community as community_louvain
# 使用Louvain算法
partition = community_louvain.best_partition(G)
except ImportError:
# 使用Girvan-Newman
from networkx.algorithms.community import girvan_newman
communities = girvan_newman(G)
first_level_communities = next(communities)
partition = {}
for i, comm in enumerate(first_level_communities):
for node in comm:
partition[node] = i
# 创建压缩图
G_compressed = nx.Graph()
# 为每个社区创建超级节点
community_nodes = {}
for node, community_id in partition.items():
if community_id not in community_nodes:
community_nodes[community_id] = []
community_nodes[community_id].append(node)
# 添加超级节点
for comm_id in community_nodes:
G_compressed.add_node(f"Community_{comm_id}",
size=len(community_nodes[comm_id]))
# 添加边(社区间的连接)
for (u, v) in G.edges():
comm_u = partition[u]
comm_v = partition[v]
if comm_u != comm_v:
G_compressed.add_edge(f"Community_{comm_u}",
f"Community_{comm_v}")
return G_compressed, partition
G_community, partition = compress_by_community(G)
print(f"社区数量: {len(G_community.nodes())}")
骨架提取(生成树)
# 方法3:使用最小生成树或最大生成树
def compress_by_spanning_tree(G, weight='weight', mode='maximum'):
"""使用生成树压缩网络"""
# 如果没有权重,添加随机权重
if not weight in G.edges(data=True)[0]:
for (u, v) in G.edges():
G[u][v][weight] = random.random()
if mode == 'maximum':
# 最大生成树(保留重要连接)
G_compressed = nx.maximum_spanning_tree(G, weight=weight)
else:
# 最小生成树(保留紧密连接)
G_compressed = nx.minimum_spanning_tree(G, weight=weight)
return G_compressed
G_tree = compress_by_spanning_tree(G, mode='maximum')
print(f"压缩后边数: {G_tree.number_of_edges()}")
基于介数中心性的压缩
# 方法4:保留重要节点
def compress_by_centrality(G, percentile=20):
"""保留中心性最高的节点"""
# 计算介数中心性
betweenness = nx.betweenness_centrality(G)
# 确定阈值
threshold = sorted(betweenness.values(), reverse=True)[
min(len(betweenness)-1, int(len(betweenness) * percentile / 100))
]
# 保留重要节点
nodes_to_keep = [n for n, c in betweenness.items() if c >= threshold]
G_compressed = G.subgraph(nodes_to_keep).copy()
return G_compressed
G_centrality = compress_by_centrality(G, percentile=30)
print(f"原始节点数: {G.number_of_nodes()}, 压缩后: {G_centrality.number_of_nodes()}")
综合压缩示例
# 完整的压缩流程示例
def complete_compression_pipeline(G, methods=['degree', 'community', 'tree'],
degree_threshold=10, percentile=30):
"""综合使用多种压缩方法"""
results = {}
for method in methods:
if method == 'degree':
# 基于度的压缩
compressed = compress_by_degree(G.copy(), degree_threshold)
results['degree'] = {
'graph': compressed,
'nodes': compressed.number_of_nodes(),
'edges': compressed.number_of_edges()
}
elif method == 'community':
# 基于社区的压缩
compressed, _ = compress_by_community(G.copy())
results['community'] = {
'graph': compressed,
'nodes': compressed.number_of_nodes(),
'edges': compressed.number_of_edges()
}
elif method == 'tree':
# 生成树压缩
compressed = compress_by_spanning_tree(G.copy())
results['tree'] = {
'graph': compressed,
'nodes': compressed.number_of_nodes(),
'edges': compressed.number_of_edges(),
'type': 'tree'
}
elif method == 'centrality':
# 中心性压缩
compressed = compress_by_centrality(G.copy(), percentile)
results['centrality'] = {
'graph': compressed,
'nodes': compressed.number_of_nodes(),
'edges': compressed.number_of_edges()
}
return results
# 执行压缩
compression_results = complete_compression_pipeline(G)
# 可视化比较
def visualize_compression_results(original_G, results):
"""可视化压缩结果"""
fig, axes = plt.subplots(2, 3, figsize=(15, 10))
# 原始图
pos = nx.spring_layout(original_G)
nx.draw(original_G, pos, ax=axes[0, 0], node_size=20, alpha=0.6)
axes[0, 0].set_title(f"原始网络\n{original_G.number_of_nodes()} nodes\n"
f"{original_G.number_of_edges()} edges")
# 各种压缩结果
for i, (method, data) in enumerate(results.items()):
row = (i + 1) // 3
col = (i + 1) % 3
compressed_G = data['graph']
nx.draw(compressed_G, nx.spring_layout(compressed_G),
ax=axes[row, col], node_size=20, alpha=0.6)
axes[row, col].set_title(f"{method}压缩\n{data['nodes']} nodes\n"
f"{data['edges']} edges")
plt.tight_layout()
plt.show()
# 可视化结果
visualize_compression_results(G, compression_results)
# 打印统计信息
print("\n=== 网络压缩统计 ===")
print(f"{'方法':<15} {'节点数':<10} {'边数':<10} {'压缩率(%)':<12}")
print("-" * 50)
print(f"{'原始网络':<15} {G.number_of_nodes():<10} {G.number_of_edges():<10} {'100':<12}")
for method, data in compression_results.items():
compression_rate = (data['nodes'] / G.number_of_nodes()) * 100
print(f"{method:<15} {data['nodes']:<10} {data['edges']:<10} "
f"{compression_rate:<12.2f}")
应用场景示例
# 实际应用:社交网络压缩
def social_network_compression_demo():
"""社交网络压缩示例"""
# 创建模拟社交网络
G = nx.watts_strogatz_graph(200, 6, 0.3)
print("=== 社交网络压缩 ===")
# 1. 基于活动度压缩(保留活跃用户)
activity = {n: random.randint(1, 100) for n in G.nodes()}
nx.set_node_attributes(G, activity, 'activity')
active_users = [n for n in G.nodes() if G.nodes[n]['activity'] > 50]
G_active = G.subgraph(active_users).copy()
print(f"活跃用户网络: {G_active.number_of_nodes()} 用户, "
f"{G_active.number_of_edges()} 关系")
# 2. 社区结构压缩
G_community, partition = compress_by_community(G)
print(f"社区压缩网络: {G_community.number_of_nodes()} 社区, "
f"{G_community.number_of_edges()} 社区间连接")
return G_active, G_community
# 运行示例
G_active, G_community = social_network_compression_demo()
这些方法可以根据具体需求选择使用,常见的应用场景包括:
- 数据可视化:减少网络复杂度
- 算法优化:降低计算复杂度
- 模式发现:提取网络核心结构
- 存储优化:节省存储空间
选择压缩方法时需要考虑:
- 网络类型和特征
- 保留信息的重要性
- 计算资源限制
- 应用具体需求
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播