Optimization Toolbox 的输出函数
什么是输出函数?
对于某些问题,您可能希望在每次迭代中得到优化算法的输出。例如,您可能希望找到算法计算的点的序列,并绘制这些点。为此,可创建一个优化函数在每次迭代时调用的输出函数。有关详细信息和语法,请参阅输出函数和绘图函数语法。
此示例对输出函数使用基于求解器的方法。有关基于问题的方法,请参阅基于问题的优化的输出函数。
通常,使用输出函数的求解器可以接受非线性函数作为输入。通过查看函数参考页的“选项”部分,您可以确定哪些求解器可以使用输出函数。
使用输出函数
此示例说明如何使用输出函数来监控 fmincon
求解有约束非线性优化问题的过程。在每个 fmincon
迭代结束时,输出函数执行以下操作:
绘制当前点。
将当前点及其对应的目标函数值存储在名为
history
的变量中,并将当前搜索方向存储在名为searchdir
的变量中。搜索方向是一个从当前点指向下一个点的向量。
此外,要使历史记录在 fmincon
函数之外可用,请在调用 fmincon
并返回输出函数变量的嵌套函数内执行优化。有关这种信息传递方法的详细信息,请参阅传递额外参数。此示例末尾的 runfmincon
辅助函数包含嵌套函数调用。
目标函数和约束函数
问题可以表示为最小化函数
且需要满足非线性不等式约束
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)
的列的迭代输出中。
history
的 x
字段包含 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