智能优化算法:基于适应度的进化策略解析与代码实现

智能优化算法:基于适应度的进化策略解析与代码实现

智能优化算法作为解决复杂非线性问题的关键工具,其核心在于通过模拟自然进化机制寻找最优解。其中,适应度函数作为评估个体优劣的核心指标,直接决定了算法的收敛速度与解的质量。本文将系统解析基于适应度的差分进化算法(DE)与遗传算法(GA)的实现原理,并提供可复用的Python代码框架。

一、适应度函数的核心作用与设计原则

适应度函数是进化算法的”裁判”,其设计质量直接影响算法性能。典型适应度函数需满足以下特性:

  1. 非负性:确保所有解的评估值≥0(可通过偏移量处理负值)
  2. 单调性:解的质量与适应度值呈正相关
  3. 计算效率:避免复杂运算,建议时间复杂度控制在O(n)以内
  4. 多目标处理:对于多目标优化,可采用加权求和或帕累托前沿方法

示例代码:Sphere函数(经典基准测试函数)

  1. import numpy as np
  2. def sphere_function(x):
  3. """单峰连续测试函数,全局最优在x=0处"""
  4. return np.sum(x**2)
  5. def rastrigin_function(x):
  6. """多峰测试函数,存在大量局部最优"""
  7. A = 10
  8. n = len(x)
  9. return A*n + np.sum(x**2 - A*np.cos(2*np.pi*x))

二、差分进化算法实现与优化

差分进化通过种群差异产生变异向量,其变异策略直接影响搜索能力。典型DE/rand/1策略实现如下:

  1. def differential_evolution(obj_func, bounds, pop_size=50,
  2. F=0.8, CR=0.9, max_gen=1000):
  3. """
  4. 差分进化算法实现
  5. 参数:
  6. obj_func: 目标函数
  7. bounds: 变量边界 [(min,max),...]
  8. F: 缩放因子(0.4-1.0)
  9. CR: 交叉概率(0.1-1.0)
  10. """
  11. dim = len(bounds)
  12. population = np.random.rand(pop_size, dim)
  13. min_b, max_b = np.array(bounds).T
  14. diff = np.fabs(min_b - max_b)
  15. population = min_b + population * diff # 初始化种群
  16. fitness = np.array([obj_func(ind) for ind in population])
  17. best_idx = np.argmin(fitness)
  18. best = population[best_idx]
  19. for _ in range(max_gen):
  20. for i in range(pop_size):
  21. # 选择三个不同个体
  22. candidates = np.arange(pop_size)
  23. candidates = np.delete(candidates, i)
  24. a, b, c = population[np.random.choice(candidates, 3, replace=False)]
  25. # 变异操作
  26. mutant = a + F * (b - c)
  27. mutant = np.clip(mutant, min_b, max_b) # 边界处理
  28. # 交叉操作
  29. cross_points = np.random.rand(dim) < CR
  30. if not np.any(cross_points):
  31. cross_points[np.random.randint(0, dim)] = True
  32. trial = np.where(cross_points, mutant, population[i])
  33. # 选择操作
  34. trial_fitness = obj_func(trial)
  35. if trial_fitness < fitness[i]:
  36. population[i] = trial
  37. fitness[i] = trial_fitness
  38. if trial_fitness < fitness[best_idx]:
  39. best_idx = i
  40. best = trial.copy()
  41. # 动态调整参数(可选)
  42. F = 0.5 + 0.5 * np.random.rand() # 自适应缩放因子
  43. return best, fitness[best_idx]

关键参数优化建议

  1. 缩放因子F:复杂问题建议0.5-0.8,简单问题可增大至0.9
  2. 交叉概率CR:离散问题建议0.9-1.0,连续问题0.7-0.9
  3. 种群规模:维度×5~维度×10(经验法则)

三、遗传算法的适应度驱动实现

遗传算法通过选择、交叉、变异三个操作实现进化,其适应度设计需特别注意比例选择中的缩放问题。

  1. def genetic_algorithm(obj_func, bounds, pop_size=100,
  2. cx_prob=0.7, mut_prob=0.1,
  3. max_gen=200, elitism=True):
  4. """
  5. 遗传算法实现(实数编码)
  6. 参数:
  7. cx_prob: 交叉概率
  8. mut_prob: 变异概率
  9. elitism: 是否保留最优个体
  10. """
  11. dim = len(bounds)
  12. min_b, max_b = np.array(bounds).T
  13. # 初始化种群
  14. population = min_b + np.random.rand(pop_size, dim) * (max_b - min_b)
  15. for gen in range(max_gen):
  16. # 评估适应度
  17. fitness = np.array([obj_func(ind) for ind in population])
  18. # 选择操作(轮盘赌选择)
  19. fitness_inv = 1 / (fitness + 1e-10) # 最小化问题转换
  20. prob = fitness_inv / np.sum(fitness_inv)
  21. idx = np.random.choice(pop_size, pop_size, p=prob)
  22. mating_pool = population[idx]
  23. # 精英保留
  24. if elitism:
  25. best_idx = np.argmin(fitness)
  26. best = population[best_idx].copy()
  27. # 交叉操作(模拟二进制交叉SBX)
  28. offspring = np.zeros_like(population)
  29. for i in range(0, pop_size, 2):
  30. if i+1 >= pop_size:
  31. offspring[i] = mating_pool[i]
  32. break
  33. parent1, parent2 = mating_pool[i], mating_pool[i+1]
  34. if np.random.rand() < cx_prob:
  35. beta = np.random.rand(*parent1.shape)
  36. offspring[i] = beta * parent1 + (1-beta) * parent2
  37. offspring[i+1] = (1-beta) * parent1 + beta * parent2
  38. else:
  39. offspring[i], offspring[i+1] = parent1, parent2
  40. # 变异操作(多项式变异)
  41. for i in range(pop_size):
  42. if np.random.rand() < mut_prob:
  43. mutant = offspring[i]
  44. for d in range(dim):
  45. if np.random.rand() < 1/dim: # 维度均匀选择
  46. u = np.random.rand()
  47. delta = 1.0 if u < 0.5 else 0.0
  48. if u < 0.5:
  49. xy = 1.0 - delta
  50. val = 2.0*u + (1.0-2.0*u)*(xy**(dim+1))
  51. else:
  52. xy = 1.0 - (1.0-delta)
  53. val = 2.0*(1.0-u) + 2.0*(u-0.5)*(xy**(dim+1))
  54. mutant[d] += (max_b[d]-min_b[d]) * val
  55. offspring[i] = np.clip(mutant, min_b, max_b)
  56. population = offspring
  57. # 精英替换
  58. if elitism:
  59. current_fitness = np.array([obj_func(ind) for ind in population])
  60. worst_idx = np.argmax(current_fitness)
  61. if fitness[best_idx] < current_fitness[worst_idx]:
  62. population[worst_idx] = best
  63. final_fitness = np.array([obj_func(ind) for ind in population])
  64. best_idx = np.argmin(final_fitness)
  65. return population[best_idx], final_fitness[best_idx]

遗传算法优化技巧

  1. 选择压力控制:通过线性缩放或排序缩放防止过早收敛
  2. 交叉算子选择:SBX适用于实数编码,单点交叉适用于二进制编码
  3. 变异强度调整:多项式变异参数η建议取20-50

四、工程实践中的关键问题处理

1. 约束优化处理

对于带约束问题,可采用以下方法:

  • 罚函数法:将约束违反量加入适应度

    1. def constrained_obj(x, constraints, penalty_factor=1e6):
    2. """带约束的目标函数"""
    3. constraint_violations = np.sum([max(0, c(x)) for c in constraints])
    4. return obj_func(x) + penalty_factor * constraint_violations
  • 修复算子:将不可行解投影到可行域

2. 多模态优化

对于存在多个全局最优的问题,可采用:

  • niching方法:维持多个子种群
  • 拥挤机制:在适应度评估中考虑个体密度

3. 并行化实现

利用多进程加速适应度评估:

  1. from multiprocessing import Pool
  2. def parallel_eval(population, obj_func):
  3. with Pool() as pool:
  4. fitness = pool.map(obj_func, population)
  5. return np.array(fitness)

五、性能评估与调优建议

  1. 收敛性分析:记录每代最优适应度,绘制收敛曲线
  2. 参数敏感性测试:通过实验确定关键参数的最佳组合
  3. 混合策略:结合局部搜索算法(如Nelder-Mead)提升精度
  4. 早停机制:当适应度改进小于阈值时提前终止

典型优化流程

  1. 问题建模与适应度函数设计
  2. 算法参数初始化(建议从默认参数开始)
  3. 运行多次独立实验(建议≥30次)
  4. 统计分析解的质量与稳定性
  5. 参数微调与算法改进

通过系统掌握适应度驱动的优化算法设计与实现,开发者能够有效解决工程中的复杂优化问题。实际应用中需结合具体问题特点进行算法定制,并通过大量实验验证算法性能。