Main Content

Optimization Toolbox 的输出函数

什么是输出函数?

对于某些问题,您可能希望在每次迭代中得到优化算法的输出。例如,您可能希望找到算法计算的点的序列,并绘制这些点。为此,可创建一个优化函数在每次迭代时调用的输出函数。有关详细信息和语法,请参阅Output Function and Plot Function Syntax

此示例对输出函数使用基于求解器的方法。有关基于问题的方法,请参阅Output Function for Problem-Based Optimization

通常,使用输出函数的求解器可以接受非线性函数作为输入。通过查看函数参考页的“选项”部分,您可以确定哪些求解器可以使用输出函数。

使用输出函数

此示例说明如何使用输出函数来监控 fmincon 求解有约束非线性优化问题的过程。在每个 fmincon 迭代结束时,输出函数执行以下操作:

  • 绘制当前点。

  • 将当前点及其对应的目标函数值存储在名为 history 的变量中,并将当前搜索方向存储在名为 searchdir 的变量中。搜索方向是一个从当前点指向下一个点的向量。

此外,要使历史记录在 fmincon 函数之外可用,请在调用 fmincon 并返回输出函数变量的嵌套函数内执行优化。有关这种信息传递方法的详细信息,请参阅传递额外参数此示例末尾runfmincon 辅助函数包含嵌套函数调用。

目标函数和约束函数

问题可以表示为最小化函数

f(x)=exp(x1)(4x12+2x22+4x1x2+2x2+1)

且需要满足非线性不等式约束

x1+x2-x1x23/2x1x2-10.

runfmincon 中嵌套的 objfun 函数会实现目标函数。runfmincon 中嵌套的 confun 函数会实现约束函数。

调用求解器

要获得问题的解并查看 fmincon 迭代的历史记录,请调用 runfmincon 函数。

[xsol,fval,history,searchdir] = runfmincon;
                                Max     Line search  Directional  First-order 
 Iter F-count        f(x)   constraint   steplength   derivative   optimality Procedure 
    0      3       1.8394          0.5                                         Infeasible start point
    1      6      1.85127     -0.09197            1        0.109        0.778   
    2      9     0.300167         9.33            1       -0.117        0.313  Hessian modified twice  
    3     12     0.529835       0.9209            1         0.12        0.232   
    4     16     0.186965       -1.517          0.5       -0.224         0.13   
    5     19    0.0729085       0.3313            1       -0.121        0.054   
    6     22    0.0353323     -0.03303            1      -0.0542       0.0271   
    7     25    0.0235566     0.003184            1      -0.0271      0.00587   
    8     28    0.0235504    9.031e-08            1      -0.0146     8.51e-07   
Active inequalities (to within options.ConstraintTolerance = 1e-06):
  lower      upper     ineqlin   ineqnonlin
                                     1
                                     2

Local minimum found that satisfies the constraints.

Optimization completed because the objective function is non-decreasing in 
feasible directions, to within the value of the optimality tolerance,
and constraints are satisfied to within the  value of the constraint tolerance.

输出函数会创建由 fmincon 计算的点的图。每个点都用其迭代序号来标注。最优点出现在第八次迭代时。序列中的最后两个点非常接近,以致几乎重叠。

输出 history 是一个包含两个字段的结构体。

disp(history)
       x: [9x2 double]
    fval: [9x1 double]

history 中的 fval 字段包含与 fmincon 计算的点序列对应的目标函数值。

disp(history.fval)
    1.8394
    1.8513
    0.3002
    0.5298
    0.1870
    0.0729
    0.0353
    0.0236
    0.0236

这些相同的值显示在标题为 f(x) 的列的迭代输出中。

historyx 字段包含 fmincon 计算的点的序列。

disp(history.x)
   -1.0000    1.0000
   -1.3679    1.2500
   -5.5708    3.4699
   -4.8000    2.2752
   -6.7054    1.2618
   -8.0679    1.0186
   -9.0230    1.0532
   -9.5471    1.0471
   -9.5474    1.0474

searchdir 输出包含每次迭代时 fmincon 的搜索方向。搜索方向是一个向量,从当前迭代时计算的点指向下一次迭代时计算的点。

disp(searchdir)
   -0.3679    0.2500
   -4.2029    2.2199
    0.7708   -1.1947
   -3.8108   -2.0268
   -1.3625   -0.2432
   -0.9552    0.0346
   -0.5241   -0.0061
   -0.0003    0.0003

辅助函数

以下代码创建 runfmincon 函数,它包含 outfun 输出函数、objfun 目标函数和 confun 非线性约束函数作为嵌套函数。

function [xsol,fval,history,searchdir] = runfmincon
 
% Set up shared variables with outfun
history.x = [];
history.fval = [];
searchdir = [];
 
% Call optimization
x0 = [-1 1];
options = optimoptions(@fmincon,'OutputFcn',@outfun,... 
    'Display','iter','Algorithm','active-set');
[xsol,fval] = fmincon(@objfun,x0,[],[],[],[],[],[],@confun,options);
 
 function stop = outfun(x,optimValues,state)
     stop = false;
 
     switch state
         case 'init'
             hold on
         case 'iter'
         % Concatenate current point and objective function
         % value with history. x must be a row vector.
           history.fval = [history.fval; optimValues.fval];
           history.x = [history.x; x];
         % Concatenate current search direction with 
         % searchdir.
           searchdir = [searchdir;... 
                        optimValues.searchdirection'];
           plot(x(1),x(2),'o');
         % Label points with iteration number and add title.
         % Add .15 to x(1) to separate label from plotted 'o'.
           text(x(1)+.15,x(2),... 
                num2str(optimValues.iteration));
           title('Sequence of Points Computed by fmincon');
         case 'done'
             hold off
         otherwise
     end
 end
 
 function f = objfun(x)
     f = exp(x(1))*(4*x(1)^2 + 2*x(2)^2 + 4*x(1)*x(2) +... 
                    2*x(2) + 1);
 end
 
 function [c, ceq] = confun(x)
     % Nonlinear inequality constraints
     c = [1.5 + x(1)*x(2) - x(1) - x(2);
         -x(1)*x(2) - 10];
     % Nonlinear equality constraints
     ceq = [];
 end
end

相关主题