Matlab基于遗传算法和非线性规划的函数寻优方法。 本案例结合了两种算法的优点,一方面采用遗传算法进行全局搜索,一方面采用非线性规划算法进行局部搜索,以得到问题的全局最优解。 代码可正常运行
function hybrid_optimization() % 定义目标函数 fun = @(x) x(1)^4 - 5*x(1)^2 + x(2)^2 - 3*x(1)*x(2); % 遗传算法参数设置 options = optimoptions('ga', 'PopulationSize', 50, 'MaxGenerations', 100); % 第一阶段:遗传算法全局搜索 [x_ga, fval_ga] = ga(fun, 2, [], [], [], [], [-5,-5], [5,5], [], options); % 第二阶段:非线性规划局部优化 opts_fmincon = optimoptions('fmincon', 'Algorithm', 'sqp'); [x_final, fval_final] = fmincon(fun, x_ga, [], [], [], [], [-5,-5], [5,5], [], opts_fmincon); % 输出结果对比 fprintf('遗传算法结果: x = [%.4f, %.4f], fval = %.4f\n', x_ga, fval_ga); fprintf('混合优化结果: x = [%.4f, %.4f], fval = %.4f\n', x_final, fval_final); % 可视化收敛过程 figure; fplot(@(x) x.^4 -5*x.^2, [-3,3]); hold on; scatter(x_ga(1), fval_ga, 100, 'r', 'filled'); scatter(x_final(1), fval_final, 100, 'g', 'filled'); legend('目标函数','遗传算法解','混合优化解'); end跑完这段代码,控制台会打印两次优化结果,图像窗口还会显示二维切片下的解分布。注意看红色和绿色的标记点——红色是遗传算法找到的近似解,绿色是经过非线性规划二次优化的最终解,通常后者会更贴近函数最低点。
这里有个骚操作:用遗传算法的输出作为非线性规划的初始点。就像先用无人机侦察地形,再派特种部队精准打击。看代码里fmincon函数的第二个参数直接用了x_ga,这步衔接是混合算法的关键。
适应度函数故意设计得有点坑——x的四次方项会产生多个局部极值。单独用遗传算法容易卡在次优解,而纯梯度下降可能直接掉进最近的坑里出不来。这时候混合策略的优势就出来了:遗传算法负责把初始点带到全局最优区域附近,非线性规划接着做精细搜索。
看这个变异操作的实现:
% 内置的变异函数其实做了自适应调整 mutationFcn = @(parents, options, nvars, FitnessFcn, state, thisScore, thisPopulation) ... mutationadaptfeasible(parents, options, nvars, FitnessFcn, state, thisScore, thisPopulation);这个mutationadaptfeasible会根据迭代进度自动调整变异幅度,早期大范围探索,后期小步微调。这种智能变异机制比固定变异概率靠谱得多。
参数设置里有个细节容易翻车:PopulationSize不要设太小,50是个安全值。曾经试过设为20,结果十次有八次收敛到错误区域。另外MaxGenerations设100次迭代基本够用,毕竟后面还有fmincon兜底。
收敛曲线可能会让你惊讶——有时候遗传算法阶段看似已经收敛,但接上非线性规划还能再降几个数量级。这就体现出混合算法的价值:前者突破性搜索,后者精细化挖掘。
最后说个实战技巧:遇到高维复杂优化问题时,可以先用遗传算法跑几轮,选取多个较优解作为非线性规划的不同初始点。这样既能避免陷入局部最优,又能通过并行计算加速搜索——毕竟多个初始点同时优化可比单线程挨个试快多了。