如何加速Python中的遗传算法?基于给定代码的优化需求
遗传算法代码加速方案(放弃突变逻辑)
原代码的核心瓶颈在于嵌套循环的逐元素操作,以及动态列表扩容的开销。以下是几种针对“放弃生成新元素(突变)逻辑”的加速方案:
一、使用Numpy向量化操作(最优方案)
利用Numpy的向量化运算替代Python循环,底层基于C实现,能大幅提升速度。直接批量生成索引并完成元素选取:
import numpy as np import time ww = get_w() # 将列表转换为Numpy数组,便于批量操作 ww_np = np.array(ww) num_individuals, num_genes = ww_np.shape t = time.time() # 一次性生成所有个体的基因索引,形状为(个体数, 基因数) delta_w = np.random.choice(num_individuals, size=(num_individuals, num_genes), p=rand) # 通过Numpy高级索引批量选取元素,直接得到新种群 new_w = ww_np[np.arange(num_individuals)[:, None], delta_w] print(time.time() - t)
二、提前预分配列表内存
如果坚持使用原生Python列表,提前创建固定大小的列表结构,避免append操作的动态扩容开销:
import random as r import time ww = get_w() num_individuals = len(ww) num_genes = len(ww[0]) if num_individuals > 0 else 0 t = time.time() # 提前创建空列表结构,避免动态扩容 new_w = [[0.0 for _ in range(num_genes)] for _ in range(num_individuals)] for i in range(num_individuals): delta_w = r.choices(range(num_individuals), weights=rand, k=num_genes) # 直接赋值而非append for x in range(num_genes): new_w[i][x] = ww[i][delta_w[x]] print(time.time() - t)
三、用Numba JIT编译加速循环
如果不想大幅修改代码结构,使用Numba将循环函数编译为机器码,接近C语言的执行速度:
import numpy as np import time from numba import njit @njit def generate_new_w(ww, rand, num_individuals, num_genes): new_w = np.empty((num_individuals, num_genes), dtype=np.float64) for i in range(num_individuals): # 使用Numba支持的Numpy随机函数生成索引 delta_w = np.random.choice(num_individuals, size=num_genes, p=rand) for x in range(num_genes): new_w[i][x] = ww[i][delta_w[x]] return new_w ww = get_w() ww_np = np.array(ww) num_individuals, num_genes = ww_np.shape t = time.time() new_w = generate_new_w(ww_np, rand, num_individuals, num_genes) print(time.time() - t)
方案对比
- Numpy向量化方案速度提升最显著,适合大规模种群场景;
- 预分配列表仅能小幅优化,适合小规模数据;
- Numba编译无需大幅重构代码,速度介于前两者之间。
内容的提问来源于stack exchange,提问作者pythenka007
相关产品推荐
相关产品推荐

