使用PyGAD优化函数时如何强制基因取非零值?
解决PyGAD中基因超出取值范围/变为零的问题
针对你遇到的参数跳出设定范围甚至变为零的情况,有几个直接有效的解决办法:
1. 自定义约束型突变函数
替换默认的adaptive突变,自己实现一个严格遵守每个基因取值范围的突变逻辑,确保突变后的值不会超出你定义的gene_space区间——因为你的gene_space本身没有零值区间,自然也就不会出现零。
示例代码:
import numpy as np import pygad def custom_mutation(offspring, ga_instance): # 遍历每个后代的每个基因 for idx, offspring_chromosome in enumerate(offspring): for gene_idx in range(ga_instance.num_genes): # 获取当前基因的取值范围 gene_min = ga_instance.gene_space[gene_idx].min() gene_max = ga_instance.gene_space[gene_idx].max() # 按设定概率进行突变 if np.random.random() < ga_instance.mutation_probability[0]: # 生成范围内的随机突变值 mutated_gene = np.random.uniform(gene_min, gene_max) offspring[idx, gene_idx] = mutated_gene return offspring # 在GA配置中替换突变类型为自定义函数 ga_instance = pygad.GA(num_generations=num_generations, num_parents_mating=num_parents_mating, fitness_func=fitness_function, sol_per_pop=sol_per_pop, num_genes=num_genes, on_generation=callback_generation, crossover_type=crossover_func, parent_selection_type=parent_selection_func, gene_space=gene_space, mutation_type=custom_mutation, mutation_probability = [0.5, 0.1])
2. 在适应度函数中添加惩罚机制
如果某个参数超出设定范围或者为零,直接给该个体的适应度打极低的分数,让遗传算法自动淘汰这类不符合要求的解。
示例代码:
def fitness_function(ga_instance, solution, solution_idx): # 检查每个参数是否符合要求 valid = True for gene_idx in range(len(solution)): gene_min = ga_instance.gene_space[gene_idx].min() gene_max = ga_instance.gene_space[gene_idx].max() if solution[gene_idx] < gene_min or solution[gene_idx] > gene_max or solution[gene_idx] == 0: valid = False break # 无效个体返回极小适应度 if not valid: return -1e9 # 原有适应度计算逻辑 # ...(你的实验数据拟合误差计算等) return fitness_value
3. 在回调函数中手动修正参数范围
利用on_generation回调,在每一代迭代后,将所有个体的基因值截断到对应的gene_space范围内,从根源上避免超出范围的情况。
示例代码:
def callback_generation(ga_instance): # 遍历所有个体,修正超出范围的基因 for idx, solution in enumerate(ga_instance.population): for gene_idx in range(len(solution)): gene_min = ga_instance.gene_space[gene_idx].min() gene_max = ga_instance.gene_space[gene_idx].max() # 截断到设定区间内 solution[gene_idx] = np.clip(solution[gene_idx], gene_min, gene_max) ga_instance.population[idx] = solution # 原有回调逻辑 # ... # 保持原有GA配置,仅修改回调函数即可
以上方法可单独使用,也可组合实施,确保参数严格遵守设定的取值范围且不会出现零值。
内容的提问来源于stack exchange,提问作者Raúl Lazo-Molina
相关产品推荐
相关产品推荐

