基于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

六、性能优化技巧

  1. 稀疏矩阵处理

    options = optimoptions(options, 'HessianFcn', 'sparse');
    
  2. 并行计算加速

    options = optimoptions(options, 'UseParallel', true);
    
  3. 梯度检查

    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

九、参考

  1. MathWorks官方文档: fmincon使用指南 ww2.mathworks.cn/help/optim/ug/fmincon.html
  2. 非线性优化函数fmincon函数程序 www.youwenfan.com/contentcnk/78282.html
  3. 《最优化理论与方法》袁亚湘著
  4. Nocedal, J., & Wright, S. J. (2006). Numerical Optimization
posted @ 2025-10-29 09:32  alloutlove  阅读(8)  评论(0)    收藏  举报