遗传算法锦标赛选择如何避免选出两个相同的亲本?
遗传算法锦标赛选择返回重复亲本的解决方案
核心问题根因
- 锦标赛参数设置不合理:你设置的
k=4正好等于种群总规模,每次锦标赛会遍历全部4个个体,最终必然固定选出得分最低(对应你规则中适应度最高)的个体(得分34对应的索引3的个体),两次调用函数自然会返回完全相同的亲本。 - 原锦标赛函数逻辑错误:循环比较时仅将候选个体与最初随机选取的
first_pick比较,没有将前一轮选出的winner作为比较基准,完全不符合锦标赛选择的规则,进一步加剧了选择结果的固定性。
修复实现方案
1. 重写锦标赛选择函数
新增排除已选个体的参数,修正比较逻辑:
import numpy as np def tournament_selection(population, scores, k=3, excluded_idx=None): # 生成可选索引列表,排除已经选中的亲本索引 available_indices = list(range(len(population))) if excluded_idx is not None: available_indices.remove(excluded_idx) # 无放回随机选取k个候选个体 candidate_indices = np.random.choice(available_indices, size=k, replace=False) # 选出得分最小的个体(对应适应度最高) winner_idx = candidate_indices[np.argmin(scores[candidate_indices])] return winner_idx, population[winner_idx, :]
说明:将默认k值调整为3,避免等于种群规模导致每次全局选最优,你也可以根据种群规模调整为种群总数的1/10~1/4区间的值
2. 调整调用逻辑,选第二个亲本时排除第一个的索引
# 先将得分转为numpy数组方便索引操作 scores = np.array([44,56,63,34]) for i in range(0, len(population), 2): # 选取第一个亲本 p1_idx, parent_1 = tournament_selection(population, scores) # 选取第二个亲本时传入第一个的索引进行排除 p2_idx, parent_2 = tournament_selection(population, scores, excluded_idx=p1_idx) # 后续执行交叉、变异等遗传操作即可
可选优化方案
如果你的后续场景允许小概率出现重复亲本,不需要强制排除,只需要把k值调整到远小于种群规模的范围,即可大幅降低重复选择的概率,不需要额外加排除逻辑。
内容的提问来源于stack exchange,提问作者Zzyy
相关产品推荐
相关产品推荐

