一、遗传算法是个啥玩意儿?

说实话,第一次听说遗传算法的时候,我还以为是什么生物课的内容。后来才知道,这玩意儿其实是计算机科学里的一种优化算法,灵感确实来自生物进化过程。简单来说,就是模拟自然界"物竞天择,适者生存"那一套。

在MATLAB里实现遗传算法特别方便,因为它自带了一个强大的全局优化工具箱。我们可以用它来解决那些传统优化方法搞不定的复杂问题,特别是那些目标函数不连续、不可导或者有多个局部最优解的情况。

二、MATLAB遗传算法工具箱初体验

让我们先来个简单的例子热热身。假设我们要优化一个简单的函数:f(x) = x*sin(10πx)+2.0,x的范围是[-1,2]。这个函数有很多局部极值点,用传统方法很容易陷入局部最优。

% 定义目标函数
fun = @(x) x.*sin(10*pi*x) + 2.0;

% 设置遗传算法选项
options = optimoptions('ga', 'PopulationSize', 50, ...
                      'MaxGenerations', 100, ...
                      'FunctionTolerance', 1e-6, ...
                      'PlotFcn', @gaplotbestf);

% 运行遗传算法
[x, fval] = ga(fun, 1, [], [], [], [], -1, 2, [], options);

% 显示结果
fprintf('找到的最优解在 x = %f, 函数值 f(x) = %f\n', x, fval);

这个例子展示了遗传算法的基本用法。我们定义了一个目标函数,设置了一些算法参数,然后让MATLAB帮我们找到全局最优解。'gaplotbestf'这个绘图函数特别有用,可以实时看到算法收敛的过程。

三、工程优化实战:机械臂轨迹规划

现在让我们看一个更实际的工程问题。假设我们要优化一个三自由度机械臂的轨迹,使得它在移动过程中能耗最小,同时避免与障碍物碰撞。

% 机械臂轨迹优化问题
% 定义目标函数:能耗 + 碰撞惩罚
function cost = armTrajectoryCost(theta)
    % theta是3xN的矩阵,表示三个关节在N个时间点的角度
    
    % 计算能耗(与角度变化率成正比)
    energy = sum(sum(diff(theta,1,2).^2));
    
    % 碰撞检测惩罚项
    collisionPenalty = 0;
    for t = 1:size(theta,2)
        % 假设障碍物在(0.5,0.5)位置
        [x,y] = forwardKinematics(theta(:,t));
        distToObstacle = sqrt((x-0.5).^2 + (y-0.5).^2);
        if distToObstacle < 0.3
            collisionPenalty = collisionPenalty + 1000*(0.3-distToObstacle);
        end
    end
    
    cost = energy + collisionPenalty;
end

% 设置遗传算法参数
nvars = 30; % 10个时间点 × 3个关节
lb = [-pi -pi -pi]'; % 关节角度下限
ub = [pi pi pi]';    % 关节角度上限
options = optimoptions('ga', ...
                      'PopulationSize', 100, ...
                      'MaxGenerations', 200, ...
                      'UseVectorized', true, ...
                      'Display', 'iter');

% 运行优化
[bestTheta, bestCost] = ga(@armTrajectoryCost, nvars, ...
                          [], [], [], [], lb, ub, [], options);

这个例子展示了遗传算法处理复杂约束问题的能力。我们不仅要优化能耗,还要避免碰撞,这在实际工程中非常常见。遗传算法的优势在于它能同时考虑多个目标,通过适应度函数的设计来平衡各种需求。

四、参数调优的艺术

遗传算法的性能很大程度上取决于参数设置。下面是一些关键参数及其影响:

  1. 种群大小(PopulationSize):太小会导致早熟收敛,太大会增加计算量。一般建议在50-200之间。

  2. 最大代数(MaxGenerations):控制算法运行时间。可以结合函数容忍度(FunctionTolerance)一起使用。

  3. 选择函数(SelectionFcn):决定如何选择父代。MATLAB提供了'tournament'和'roulette'等选项。

  4. 交叉概率(CrossoverFraction):通常设置在0.7-0.9之间。

  5. 变异概率(MutationFcn):保持种群多样性的关键。

% 高级参数设置示例
options = optimoptions('ga', ...
    'PopulationSize', 150, ...
    'MaxGenerations', 300, ...
    'CrossoverFraction', 0.85, ...
    'MutationFcn', {@mutationadaptfeasible, 0.05}, ...
    'SelectionFcn', 'selectiontournament', ...
    'EliteCount', 5, ...
    'FunctionTolerance', 1e-8, ...
    'ConstraintTolerance', 1e-6);

五、遗传算法的优缺点分析

优点:

  1. 不需要目标函数可导或连续
  2. 能够跳出局部最优解
  3. 适用于高维问题
  4. 可以处理各种约束条件

缺点:

  1. 计算成本较高
  2. 结果可能每次都不一样
  3. 需要仔细调参
  4. 收敛速度可能较慢

六、实际应用中的注意事项

  1. 编码方式:MATLAB默认使用实数编码,但对于某些离散问题可能需要自定义编码。

  2. 约束处理:可以使用罚函数法,或者MATLAB内置的线性/非线性约束处理。

  3. 并行计算:对于耗时问题,可以启用并行计算加速。

% 启用并行计算的示例
options = optimoptions('ga', 'UseParallel', true);
  1. 混合方法:可以考虑在遗传算法后接一个局部搜索方法,提高精度。

七、总结

遗传算法是MATLAB优化工具箱中的一把瑞士军刀,特别适合处理那些传统优化方法搞不定的复杂问题。虽然它需要一定的调参经验,但一旦掌握,就能解决很多实际工程中的棘手问题。记住,没有放之四海而皆准的参数设置,需要根据具体问题进行调整。

对于初学者,建议从默认参数开始,然后逐步调整。多看看算法运行过程中的可视化结果,这能帮助你理解算法是如何工作的。最后,别忘了MATLAB的帮助文档是个宝库,里面有很多高级用法的示例。