基于MATLAB的fmincon函数实现非线性优化并提取迭代参数变化
一、原理与流程
1. 算法框架
初始化 \(x_0\)
while 未收敛:
计算搜索方向 \(d_k\)
线搜索确定步长 \(α_k\)
\(x_{k+1}=x_k+α_kd_k\) // 记录迭代参数
检查收敛条件
end
二、代码实现
1. 目标函数定义
% 定义Rosenbrock函数(带梯度)
function [f,g] = rosenbrock(x)
f = 100*(x(2)-x(1)^2)^2 + (1-x(1))^2;
if nargout > 1
g = [-400*(x(2)-x(1)^2)*x(1)-2*(1-x(1)), ...
200*(x(2)-x(1)^2)];
end
end
2. 输出函数实现
% 自定义输出函数(记录迭代参数)
function stop = myOutputFcn(x, optimValues, state)
persistent iterData
if isempty(iterData)
iterData.x = x; % 初始点
iterData.fval = optimValues.fval;
iterData.iter = 0;
else
iterData.iter = iterData.iter + 1;
iterData.x = [iterData.x; x]; % 记录每次迭代点
iterData.fval = [iterData.fval; optimValues.fval];
end
% 可选:实时绘制参数变化
figure(1); clf;
plot(1:iterData.iter, iterData.x(:,1), 'r-o', ...
1:iterData.iter, iterData.x(:,2), 'b-s');
legend('x1', 'x2'); xlabel('Iteration'); ylabel('Parameter Value');
drawnow;
stop = false; % 不终止优化
end
3. 主程序调用
% 优化参数设置
options = optimoptions('fmincon',...
'Algorithm', 'interior-point',...
'Display', 'iter',...
'OutputFcn', @myOutputFcn,...
'MaxIter', 50);
% 初始点与约束
x0 = [0, 0];
A = [-1, 2]; b = 1; % 线性约束 x1 + 2x2 <= 1
% 执行优化
[x_opt, fval] = fmincon(@rosenbrock, x0, A, b);
% 提取迭代数据
iterData = iterData(2:end); % 去除初始点
三、迭代过程分析
1.. 关键指标提取
% 提取迭代数据
steps = size(iterData, 1);
x1_changes = iterData(:,1);
x2_changes = iterData(:,2);
% 统计信息
mean_x1 = mean(x1_changes);
std_x1 = std(x1_changes);
fprintf('x1变化: 均值=%.4f, 标准差=%.4f\n', mean_x1, std_x1);
2. 收敛性分析
% 目标函数值变化
figure;
semilogy(1:steps, iterData.fval, '-o');
xlabel('Iteration'); ylabel('Objective Value');
title('Convergence Curve');
grid on;
四、增强功能实现
1. 多约束条件支持
% 非线性约束函数
function [c, ceq] = nonlinearConstraints(x)
c = x(1)^2 + x(2)^2 - 1; % 圆约束 x1² + x2² <= 1
ceq = [];
end
% 修改主程序调用
nonlcon = @nonlinearConstraints;
[x_opt, fval] = fmincon(@rosenbrock, x0, A, b, [], [], [], [], nonlcon, options);
2. 自适应步长记录
% 修改输出函数
function stop = myOutputFcn(x, optimValues, state)
persistent iterData
if isempty(iterData)
iterData = struct('x',{x}, 'alpha',{optimValues.stepsize});
else
iterData.x{end+1} = x;
iterData.alpha{end+1} = optimValues.stepsize;
end
end
% 提取步长数据
steps = length(iterData.alpha);
stepSizes = cell2mat(iterData.alpha);
五、工程应用案例
1. 机械臂路径规划
% 定义目标函数(避障优化)
function f = pathPlanning(x)
obstacle = [2,3; 4,5; 6,7];
f = 0;
for i = 1:size(obstacle,1)
f = f + 1/(norm(x - obstacle(i,:)) + 1e-6); % 障碍物排斥项
end
end
% 添加约束
A = [1,1; -1,2]; b = [5; 3]; % 设计域约束
2. 参数敏感性分析
% 批量运行不同初始点
initialPoints = [-1,0; 0,1; 1,-1];
for i = 1:size(initialPoints,1)
[~, fval] = fmincon(@rosenbrock, initialPoints(i,:), A, b);
fprintf('初始点[%d]最优值: %.4f\n', i, fval);
end
六、性能优化技巧
-
稀疏矩阵处理:
options = optimoptions(options, 'HessianFcn', 'sparse'); -
并行计算加速:
options = optimoptions(options, 'UseParallel', true); -
梯度检查:
options = optimoptions(options, 'GradObj', 'on', 'GradConstr', 'on');
七、结果验证与调试
1. 收敛性验证
% 检查最终解是否满足约束
constraintViolation = A*x_opt - b;
assert(all(constraintViolation <= 1e-6));
2. 敏感性分析
% 参数扰动测试
perturbation = 1e-4*randn(size(x_opt));
perturbedX = x_opt + perturbation;
perturbedFval = rosenbrock(perturbedX);
fprintf('扰动后目标值变化: %.4e\n', abs(perturbedFval - fval));
八、完整代码仓库
% 主程序文件: optimize.m
% 输出函数文件: myOutputFcn.m
% 目标函数文件: rosenbrock.m
% 约束函数文件: nonlinearConstraints.m
九、参考
- MathWorks官方文档: fmincon使用指南 ww2.mathworks.cn/help/optim/ug/fmincon.html
- 非线性优化函数fmincon函数程序 www.youwenfan.com/contentcnk/78282.html
- 《最优化理论与方法》袁亚湘著
- Nocedal, J., & Wright, S. J. (2006). Numerical Optimization
浙公网安备 33010602011771号