Main Content

Optimization Toolbox 的输出函数

什么是输出函数?

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

此示例对输出函数使用基于求解器的方法。有关基于问题的方法,请参阅基于问题的优化的输出函数

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

使用输出函数

此示例说明如何使用输出函数来监控 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.

Figure contains an axes object. The axes object with title Sequence of Points Computed by fmincon contains 18 objects of type line, text. One or more of the lines displays its values using only markers

输出函数会创建由 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

相关主题