使用遗传算法时能否随机限制每次迭代选中的变量数量
遗传算法添加3-4个变量生效约束的实现方案
这里提供两种可直接对接你现有代码的实现方案,无需修改geneticalgorithm库源码:
方案1:个体硬修复(收敛最快,100%满足约束)
在目标函数计算前,强制将所有个体修复为仅3-4个非0值的状态,其余变量直接置0,从根源上保证约束生效:
import numpy as np def f(individual): # 复制个体避免修改原始迭代数据 fixed_ind = individual.copy() # 按系数绝对值从大到小排序取索引 abs_vals = np.abs(fixed_ind) sorted_idx = np.argsort(-abs_vals) # 随机选择保留3个还是4个生效变量 keep_num = np.random.choice([3,4]) # 其余变量强制置0 fixed_ind[sorted_idx[keep_num:]] = 0 # -------------------------- # 此处替换为你原本的目标函数计算逻辑,用修复后的fixed_ind计算损失 # 示例:假设原目标是最小化系数平方和,替换为你自己的计算逻辑即可 original_loss = np.sum(fixed_ind ** 2) # -------------------------- return original_loss
该方案所有参与迭代计算的个体都完全符合约束,不会产生无效个体,收敛效率最高。
方案2:惩罚项法(改动最小,适配灵活)
如果不想修改个体本身,可在目标函数中添加惩罚规则,让不符合约束的个体获得极差的适应度,自然被迭代淘汰:
def f(individual): # 统计非0元素数量,注意浮点数精度问题,阈值可自行调整 non_zero_cnt = np.sum(np.abs(individual) > 1e-6) # 非0数量不在3-4区间的话,返回极大惩罚值(如果你的目标是求最大值则返回极小值) if non_zero_cnt <3 or non_zero_cnt>4: return 1e18 + abs(non_zero_cnt - 3.5)*1e10 # 符合约束的个体正常计算原目标值 original_loss = 你的原目标计算逻辑(individual) return original_loss
该方案仅需修改目标函数返回逻辑,改动最小,但会存在少量无效个体占用种群配额,收敛速度稍慢。
调整后的完整运行代码
import numpy as np from geneticalgorithm import geneticalgorithm as ga # 替换为上述你选择的方案对应的目标函数f即可 def f(individual): fixed_ind = individual.copy() abs_vals = np.abs(fixed_ind) sorted_idx = np.argsort(-abs_vals) keep_num = np.random.choice([3,4]) fixed_ind[sorted_idx[keep_num:]] = 0 # 替换为你的原目标逻辑 loss = np.sum(fixed_ind ** 2) return loss len_x_coef = 13 varbound = np.array([[-1.0,1.0]]*len_x_coef) # 可微调参数适配约束场景 algorithm_param={'max_num_iteration': None, 'population_size':150, 'mutation_probability':0.05,'elit_ratio': 0.1, 'crossover_probability': 0.5,'parents_portion': 0.2, 'crossover_type':'uniform','max_iteration_without_improv':100} model=ga(function=f,dimension=len_x_coef,variable_type='real', variable_boundaries=varbound, algorithm_parameters=algorithm_param) model.run() convergence=model.report solution=model.output_dict # 最终结果处理:保留solution['variable']中绝对值最大的3-4个值,其余置0即可得到符合约束的最优系数
内容的提问来源于stack exchange,提问作者roudan
相关产品推荐
相关产品推荐

