You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用DEAP库获取遗传算法的所有可行解

基于DEAP的约束满足型遗传算法饮食方案生成问题解答

约束处理与不可行解过滤

你之前使用的tools.DeltaPenalty属于软惩罚机制,核心作用是给不可行解赋予极低适应度,让其在选择阶段更容易被淘汰,并不会直接将不可行解移出种群,因此测试时看到违反约束的个体残留是正常现象。如果需要严格过滤不可行解,可选择以下两种实现方案:

  • 方案1:将可行性校验直接写入评估函数
    这种方式逻辑最可控,不需要额外依赖装饰器,只有通过约束校验的个体才会计算真实适应度,未通过的个体直接返回最差适应度值,示例代码如下:
    def evaluate(individual):
        # 先计算各营养指标总和
        total_kcal = sum(x * y for x, y in zip(kcal_data, individual))
        total_prot = sum(x * y for x, y in zip(prot_data, individual))
        # 补全所有营养约束规则
        is_feasible = (
            7 * 1999 < total_kcal < 7 * 2001
            and 7 * 60.5 < total_prot
            # 其余脂肪、碳水、微量元素等约束按相同格式补充
        )
        if not is_feasible:
            # 返回预设的最差适应度,单目标优化返回单元素元组,多目标对应返回等长元组
            return (9999,)
        
        # 仅对可行解执行正常适应度计算,例如计算与目标营养值的偏差、食材成本、饮食多样性得分等
        fitness =  # 自定义适应度计算逻辑
        return (fitness,)
    
  • 方案2:进化流程中硬删除不可行解
    如果完全不希望不可行解参与后续交叉、变异流程,可以在每一代种群生成(交叉、变异操作完成)后,遍历所有个体删除未通过可行性校验的个体,再从当前代已有的可行解中随机复制、或重新生成新的随机个体,将种群规模补全到预设值即可。注意不要删除后直接进入下一代,否则种群规模会逐代缩减,最终导致算法提前收敛失效。

    提示:如果你的营养约束阈值比较严格,硬删除方案容易出现进化初期可行解数量不足、收敛速度慢的问题,优先选择写入评估函数的软过滤方案更稳妥。

全世代可行个体的存储与访问

DEAP内置的标准进化算法(如eaSimple)默认仅返回最终代种群,要获取全流程生成的所有可行解(包括非最优解),不需要修改框架源码,只需自行添加存储逻辑即可:

  • 第一步:初始化全局存储容器,推荐用带自动去重能力的集合存储,避免重复记录基因型完全一致的个体;如果需要按世代归档,可改用字典结构,key为世代编号,value为对应世代的可行解列表。
    # 存储格式:(个体基因型元组, 对应适应度值)
    all_feasible_solutions = set()
    
  • 第二步:将存储逻辑嵌入评估函数(覆盖率最高,不会漏掉任何新生成的个体):只要个体通过可行性校验,就先存入容器再返回适应度值,修改后的评估函数示例如下:
    def evaluate(individual):
        total_kcal = sum(x * y for x, y in zip(kcal_data, individual))
        total_prot = sum(x * y for x, y in zip(prot_data, individual))
        is_feasible = (
            7 * 1999 < total_kcal < 7 * 2001
            and 7 * 60.5 < total_prot
            # 补全其余约束
        )
        if not is_feasible:
            return (9999,)
        
        fitness = # 自定义适应度计算逻辑
        # 列表类型的个体不能存入集合,转成不可变的元组类型做去重判断
        ind_key = tuple(individual)
        if ind_key not in [item[0] for item in all_feasible_solutions]:
            all_feasible_solutions.add( (ind_key, fitness) )
        return (fitness,)
    
  • 算法运行结束后,直接读取all_feasible_solutions即可拿到所有生成过的可行解,你可以根据适应度分层抽样,筛选出多样化的符合要求的饮食方案,不需要局限于最终种群的最优个体。

优化小技巧:如果约束严格,建议初始种群生成阶段就加入可行性校验,先生成一批满足约束的个体作为初代,能大幅降低前期不可行解占比,加快收敛速度。


内容的提问来源于stack exchange,提问作者Caroline Herlev Gebara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 03:51:20