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

如何优化二进制问题的适应度函数?以除法函数场景为例

改进除法函数的适应度函数实现

当前实现的问题

你的当前fitness函数存在两个核心问题:

  1. 未处理异常场景:当b=0时,两个函数都会抛出ZeroDivisionError,当前代码会直接崩溃,无法完成适应度计算
  2. 二元极端值:仅返回0或np.inf,没有中间梯度信息,进化算法无法通过适应度的细微变化引导种群逐步优化,容易陷入局部最优或进化停滞

改进方案:分场景的连续适应度计算

我们需要区分**正常输入(b≠0)和异常输入(b=0)**两种场景,分别设计适应度计算逻辑,同时用连续的误差值替代二元结果,给进化算法提供足够的优化引导。

实现思路

  1. 捕获异常行为:对比两个函数在输入下是返回结果还是抛出异常,异常类型是否一致
  2. 正常输入场景:用绝对误差+相对误差的组合计算适应度,既反映数值差异的绝对值,也避免大数场景下的误差失真
  3. 异常输入场景:用固定的大惩罚值标记行为不一致,避免使用np.inf(多数进化算法框架无法处理无穷大值)

代码实现

import numpy as np

# 正确的除法函数
def divide(a, b):
    if b == 0:
        raise ZeroDivisionError
    return a / b

# 存在缺陷的除法函数(未处理除零)
def divide_m(a, b):
    return a / b

def fitness(a, b):
    # 捕获正确函数的执行结果或异常
    original_res = None
    original_err = None
    try:
        original_res = divide(a, b)
    except ZeroDivisionError:
        original_err = ZeroDivisionError
    
    # 捕获缺陷函数的执行结果或异常
    mutated_res = None
    mutated_err = None
    try:
        mutated_res = divide_m(a, b)
    except ZeroDivisionError:
        mutated_err = ZeroDivisionError
    
    # 场景1:两者行为一致(都抛相同异常或都返回结果)
    if original_err == mutated_err:
        if original_err is not None:
            # 都抛出除零异常,行为完全一致,适应度为0
            return 0.0
        else:
            # 计算绝对误差和相对误差,组合作为适应度(误差越大,适应度越高)
            abs_error = np.abs(original_res - mutated_res)
            # 加1e-8避免除零
            rel_error = abs_error / (np.abs(original_res) + 1e-8)
            return abs_error + rel_error
    # 场景2:行为不一致(一个抛异常,一个返回结果)
    else:
        # 严重错误,返回固定大惩罚值
        return 1000.0

适配不同进化算法的调整

如果你的进化算法是最小化适应度(即适应度越低越好),上述代码直接可用;如果是最大化适应度(即适应度越高越好),可以调整为:

def fitness_max(a, b):
    # 异常捕获部分与上述代码一致
    original_res = None
    original_err = None
    try:
        original_res = divide(a, b)
    except ZeroDivisionError:
        original_err = ZeroDivisionError
    
    mutated_res = None
    mutated_err = None
    try:
        mutated_res = divide_m(a, b)
    except ZeroDivisionError:
        mutated_err = ZeroDivisionError
    
    if original_err == mutated_err:
        if original_err is not None:
            return 1000.0  # 行为一致,适应度最高
        else:
            abs_error = np.abs(original_res - mutated_res)
            rel_error = abs_error / (np.abs(original_res) + 1e-8)
            # 误差越小,适应度越高
            return 1000.0 - (abs_error + rel_error)
    else:
        return 0.0  # 行为不一致,适应度最低

关键注意事项

  • 避免使用np.inf:用足够大的常数(如1000,可根据输入范围调整)替代,防止进化算法框架处理异常
  • 覆盖多场景测试:测试b=0、b接近0、a=0、正负数值、大数等输入,确保适应度函数能正确评估所有差异
  • 误差组合可调整:如果更关注相对误差,可以提高其权重(比如abs_error + 10*rel_error),根据你的优化目标灵活调整

内容的提问来源于stack exchange,提问作者foobar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 02:10:51