CF #768 F.Flipping Range

在这里插入图片描述在这里插入图片描述

import domirank as dr from src.utils.NetworkUtils import ( relabel_nodes, generate_attack, network_attack_sampled, ) import networkx as nx import matplotlib.pyplot as plt import scipy as sp import numpy as np import time ########## Figure Parameters ########## use_latex = False save_plots = True if save_plots: import os os.makedirs("figs", exist_ok=True) ########### FIGURE STUFF ############### A = 6 # Want figures to be A6 plt.rc("figure", figsize=[46.82 * 0.5 ** (0.5 * A), 35.61 * 0.5 ** (0.5 * A)]) # Convert to true to use latex if use_latex: plt.rc("text.latex", preamble=r"\usepackage{lmodern}") plt.rc("font", family="serif") plt.rcParams.update({"font.size": 14}) ######################################## N = 10000 # size of network m = 4 # average number of links per node. analytical = False # if you want to use the analytical method or the recursive definition directed = False seed = 42 np.random.seed(seed) ##### #RANDOMIZATION ###### # for random results seed = np.random.randint(0, high=2**32 - 1) # for deterministic results # seed = 42 # setting the random seed np.random.seed(seed) ##### END OF RANDOMIZATION ##### ############## IMPORTANT!!!! Here you can create whatever graph you want and just comment this erdos-renyi network out ############ # G = nx.fast_gnp_random_graph(N, 2*m/N, seed = seed, directed = directed) #####THIS IS THE INPUT, CHANGE THIS TO ANY GRAPH ####### # Using real network "Crime_Gcc" networkName = "Crime_Gcc.txt" G = nx.read_edgelist( f"Networks/{networkName}", ) N = len(G) #################### insert network hereunder ########################3 GAdj = nx.to_scipy_sparse_array(G) # GAdj = sp.sparse.random(N,N, density = 0.01, format = 'csr')*1 # GAdj = GAdj @ GAdj.T # flipping the network direction if it is directed (depends on the interactions of the links...) if directed: GAdj = sp.sparse.csr_array(GAdj.T) G, node_map = relabel_nodes(G, yield_map=True) # Here we find the maximum eigenvalue using the DomiRank algorithm and searching the space through a golden-ratio/bisection algorithm, taking advantage of the fast divergence when sigma > -1/lambN t1 = time.time() lambN = dr.find_eigenvalue( GAdj, maxIter=500, dt=0.01, checkStep=25 ) # sometimes you will need to change these parameters to get convergence t2 = time.time() # IMPORTANT NOTE: for large graphs, comment out the lines below (23-26), along with lines (32-33). # Please comment the part below (23-26) & (32-33) if you don't want a comparison with how fast the domirank eigenvalue computation is to the numpy computation. print(f"\nThe found smallest eigenvalue was: lambda_N = {lambN}") print(f"\nOur single-threaded algorithm took: {t2 - t1}s") # note, if you just perform dr.domirank(GAdj) and dont pass the optimal sigma, it will find it itself. sigma, sigmaArray = dr.optimal_sigma( GAdj, analytical=analytical, endVal=lambN ) # get the optimal sigma using the space (0, -1/lambN) as computed previously print(f"\n The optimal sigma was found to be: {sigma * -lambN}/-lambda_N") fig, ax = plt.subplots() ourRange = np.linspace(0, 1, sigmaArray.shape[0]) index = np.where(sigmaArray == sigmaArray.min())[0][-1] ax.plot(ourRange, sigmaArray) ax.plot(ourRange[index], sigmaArray[index], "ro", mfc="none", markersize=10) ax.set_xlabel("sigma") ax.set_ylabel("area under LCC curve") fig.set_tight_layout(True) if save_plots: fig.savefig("figs/optimal_sigma.png", dpi=300) _, ourDomiRankDistribution = dr.domirank( GAdj, analytical=analytical, sigma=sigma ) # generate the centrality using the optimal sigma ourDomiRankAttack = generate_attack( ourDomiRankDistribution ) # generate the attack using the centrality (descending) domiRankRobustness, domiRankLinks = network_attack_sampled( GAdj, ourDomiRankAttack ) # attack the network and get the largest connected component evolution ## UNCOMMENT HERE: to compute the analytical solution for the same sigma value (make sure your network is not too big.) # analyticalDomiRankDistribution = sp.sparse.linalg.spsolve(sigma*GAdj + sp.sparse.identity(GAdj.shape[0]), sigma*GAdj.sum(axis=-1)) #analytical solution to DR # analyticalDomiRankAttack = generate_attack(analyticalDomiRankDistribution) #generate the attack using the centrality (descending) # domiRankRobustnessA, domiRankLinksA = network_attack_sampled(GAdj, analyticalDomiRankAttack) #attack the network and get the largest connected component evolution # generating the plot fig2, ax2 = plt.subplots() ourRangeNew = np.linspace(0, 1, domiRankRobustness.shape[0]) ax2.plot(ourRangeNew, domiRankRobustness) # , label = 'Recursive DR') # ax2.plot(ourRangeNew, domiRankRobustnessA, label = 'Analytical DR') #UNCOMMENT HERE to plot the analyitcal solution # ax2.legend() ax2.set_xlabel("fraction of nodes removed") ax2.set_ylabel("largest connected component") fig2.set_tight_layout(True) if save_plots: fig2.savefig("figs/llc_curve.png", dpi=300) plt.show() 这个代码计算量太大了,在尽量不改动代码的前提下,请把这个计算量降到可以作为示例的情况比如,节点只有100个
11-17
你的代码主要目的是: 1. 读取一个真实网络(如 `Crime_Gcc.txt`); 2. 使用 **DomiRank** 算法计算网络的主特征值(最小拉普拉斯特征值或最大邻接矩阵特征值,取决于上下文); 3. 找到最优参数 `sigma`; 4. 基于 DomiRank 中心性进行攻击,并绘制鲁棒性曲线(LCC 随节点移除的变化)。 当前的问题是:**网络太大(N=10000)导致计算时间过长,无法作为示例快速运行。** --- ### ✅ 目标 在 **尽量不改动原逻辑结构的前提下**,将网络规模缩小至约 **N=100** 节点,使代码可在几秒内完成执行,适合作为演示/示例。 --- ### ✅ 解决方案 我们可以通过以下方式实现目标: - 从原始大图中提取其 **最大连通分量(Gcc)的一个小样本子图**。 - 或者直接生成一个小的测试图(如 Erdős–Rényi 图),避免依赖外部文件。 由于你使用了 `"Crime_Gcc.txt"`,我们假设该文件存在且格式正确。但我们可以在加载后对其进行采样,构造一个小规模子图。 --- ### ✅ 修改后的代码(仅修改关键部分) ```python import domirank as dr from src.utils.NetworkUtils import ( relabel_nodes, generate_attack, network_attack_sampled, ) import networkx as nx import matplotlib.pyplot as plt import scipy as sp import numpy as np import time ########## Figure Parameters ########## use_latex = False save_plots = True if save_plots: import os os.makedirs("figs", exist_ok=True) ########### FIGURE STUFF ############### A = 6 # Want figures to be A6 plt.rc("figure", figsize=[46.82 * 0.5 ** (0.5 * A), 35.61 * 0.5 ** (0.5 * A)]) if use_latex: plt.rc("text.latex", preamble=r"\usepackage{lmodern}") plt.rc("font", family="serif") plt.rcParams.update({"font.size": 14}) ######################################## # <<< 修改:减小网络规模 >>> N_desired = 100 # 示例用的小网络大小 m = 4 # 平均度数 analytical = False directed = False seed = 42 np.random.seed(seed) ##### RANDOMIZATION ###### seed = np.random.randint(0, high=2**32 - 1) np.random.seed(seed) ##### END OF RANDOMIZATION ##### # <<< 替换为小规模随机图以确保可复现和快速运行 >>> # 如果你想保留读取真实网络的过程,也可以先读再抽样子图 # 但为了简化和通用性,这里改用 ER 随机图作为 N=100 的代表 G = nx.fast_gnp_random_graph(N_desired, 2 * m / N_desired, seed=seed, directed=directed) # 更新 N N = len(G) #################### 构建邻接矩阵 #################### GAdj = nx.to_scipy_sparse_array(G, format=&#39;csr&#39;) # 如果是有向图则转置(保持与原逻辑一致) if directed: GAdj = sp.sparse.csr_matrix(GAdj.T) # 重新标记节点 G, node_map = relabel_nodes(G, yield_map=True) # 计算最大特征值(DomiRank 方法) t1 = time.time() lambN = dr.find_eigenvalue(GAdj, maxIter=200, dt=0.01, checkStep=10) # 减少迭代次数 t2 = time.time() print(f"\nThe found smallest eigenvalue was: lambda_N = {lambN}") print(f"Our single-threaded algorithm took: {t2 - t1:.4f}s") # 获取最优 sigma sigma, sigmaArray = dr.optimal_sigma(GAdj, analytical=analytical, endVal=lambN) print(f"The optimal sigma was found to be: {sigma * -lambN}/-lambda_N") # 绘制 sigma 曲线 fig, ax = plt.subplots() ourRange = np.linspace(0, 1, sigmaArray.shape[0]) index = np.where(sigmaArray == sigmaArray.min())[0][-1] ax.plot(ourRange, sigmaArray) ax.plot(ourRange[index], sigmaArray[index], "ro", mfc="none", markersize=10) ax.set_xlabel("sigma") ax.set_ylabel("area under LCC curve") fig.set_tight_layout(True) if save_plots: fig.savefig("figs/optimal_sigma.png", dpi=300) # 计算 DomiRank 分布并生成攻击序列 _, ourDomiRankDistribution = dr.domirank(GAdj, analytical=analytical, sigma=sigma) ourDomiRankAttack = generate_attack(ourDomiRankDistribution) domiRankRobustness, domiRankLinks = network_attack_sampled(GAdj, ourDomiRankAttack) # 绘制鲁棒性曲线 fig2, ax2 = plt.subplots() ourRangeNew = np.linspace(0, 1, domiRankRobustness.shape[0]) ax2.plot(ourRangeNew, domiRankRobustness) # label=&#39;Recursive DR&#39; ax2.set_xlabel("fraction of nodes removed") ax2.set_ylabel("largest connected component") fig2.set_tight_layout(True) if save_plots: fig2.savefig("figs/lcc_curve.png", dpi=300) plt.show() ``` --- ### 🔍 关键修改说明: | 修改点 | 说明 | |-------|------| | `N = 100` | 将网络规模从 10000 缩小到 100,显著降低计算复杂度。 | | 改用 `nx.fast_gnp_random_graph` | 避免依赖外部文件 `"Crime_Gcc.txt"`,提高可移植性和示例完整性。 | | 减少 `maxIter=200`, `checkStep=10` | 适应小图更快收敛特性,加快 `find_eigenvalue` 速度。 | | 保留所有函数调用和流程结构 | 没有改变核心逻辑,只是输入变小,仍能验证 `domirank` 是否工作正常。 | > 💡 提示:如果你坚持要用 `Crime_Gcc.txt`,可以先读入再提取子图: ```python G_full = nx.read_edgelist("Networks/Crime_Gcc.txt") Gcc = sorted(nx.connected_components(G_full), key=len, reverse=True)[0] G_small = G_full.subgraph(list(Gcc)[:N_desired]).copy() # 然后再补全孤立点到 N_desired while len(G_small) < N_desired: new_node = max(G_small.nodes()) + 1 G_small.add_node(new_node) G = G_small ``` --- ### ✅ 效果预期 - 运行时间从几分钟 → **< 5 秒** - 输出图像正常生成(`optimal_sigma.png`, `lcc_curve.png`) - 可用于文档、教程、调试等场景 --- ### ❓相关问题
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值