numpy调用np.random.choice报probabilities are not non-negative如何解决
报错原因
np.random.choice的p参数要求所有概率值必须为非负数,且总和为1,你直接用包含负数的fit_level计算概率,会出现负概率,触发报错。- 你的代码还存在一处隐性错误:
np.random.choice的a参数写的是未定义的变量arr,应当改为传入的种群参数population。
修复方案
核心思路
对原始适应度做平移修正,消除负值后再计算选择概率,是最常用的处理方案,不会改变不同个体之间的适应度相对差距。
步骤如下:
- 计算适应度数组的最小值,所有适应度减去最小值,得到全为非负的调整后适应度
- 若调整后所有适应度都为0(所有个体适应度完全相同的极端场景),统一给每个适应度加1,避免计算概率时分母为0
- 用调整后的适应度计算选择概率,再传入
np.random.choice即可
修正后完整代码
import numpy as np def select(population, fitness_arr): # 平移修正适应度,消除负值 min_fit = min(fitness_arr) adjusted_fit = [x - min_fit for x in fitness_arr] # 处理所有个体适应度相同的极端场景 total_fit = sum(adjusted_fit) if total_fit == 0: adjusted_fit = [1 for _ in adjusted_fit] total_fit = len(adjusted_fit) # 计算合法概率 probability = [x / total_fit for x in adjusted_fit] # 修正a参数错误,按概率选中个体 c = np.random.choice(a=population, size=1, replace=True, p=probability) return c # 示例参数 population = [[0, 0, 0, 1, 0, 1, 0], [1, 0, 1, 1, 0, 1, 0], [1, 0, 0, 1, 1, 0, 0], [0, 1, 1, 0, 0, 1, 0], [1, 1, 0, 0, 0, 0, 1], [0, 0, 0, 1, 0, 0, 1], [0, 0, 1, 0, 0, 1, 0]] fit_level = [-355, 0, 6167, 26, 526, 740, 315] print(select(population, fit_level))
补充说明
如果你当前的优化目标是最小化适应度(即适应度越小的个体越应该被选中),则需要在平移修正后对调整后的适应度取反再加最大值,或者做倒数处理,避免选择方向错误。
内容的提问来源于stack exchange,提问作者Joyanta J. Mondal
相关产品推荐
相关产品推荐

