对于某些问题,您可能希望在每次迭代时得到优化算法的输出。例如,您可能希望找到算法计算的点的序列并绘制这些点。为此,创建优化函数在每次迭代时调用的输出函数。看到输出函数的语法获取详细信息和语法。
本节介绍基于求解器的输出函数方法。有关基于问题的方法,请参见用于基于问题的优化的输出函数。
通常,能够使用输出函数的解算器是能够将非线性函数作为输入的解算器。可以通过查看函数引用页的选项部分,或者通过检查输出函数选项可在优化应用程序的求解。
下面的示例延续了in中的一个非线性不等式约束,调用该函数fmincon
在命令行中解决一个非线性、有约束的优化问题。本节中的示例使用一个函数文件进行调用fmincon
。该文件还包含了示例所需的所有函数,包括:
目标函数
约束函数
一个输出函数,记录由算法计算的点的历史fmincon
。在算法的每次迭代中fmincon
,输出函数:
绘制算法计算的当前点。
将该点及其对应的目标函数值存储在一个名为的变量中历史
,并将当前搜索方向存储在名为的变量中searchdir
。搜索方向是一个向量,指向当前点到下一个点的方向。
该文件的代码如下:编写示例函数文件。
指定输出函数选项
,如
选择= optimoptions (@fmincon OutputFcn, @outfun)
在哪里outfun
是输出函数的名称。调用优化函数时选项
作为输入,优化函数调用outfun
在算法的每次迭代中。
一般来说,outfun
可以是任何MATLAB®函数,但在本例中,它是一个嵌套函数中的函数文件编写示例函数文件。下面的代码定义了输出函数:
函数stop = outfun(x,optimValues,state)切换状态大小写“init”保持大小写“iter”%,将当前点和目标函数%值与历史记录连接起来。x一定是行向量。历史。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. % Add .15 to x(1) to separate label from plotted 'o' text(x(1)+.15,x(2),num2str(optimValues.iteration)); case 'done' hold off otherwise end end
看到使用句柄存储函数参数(MATLAB)获取有关嵌套函数的更多信息。
优化函数传递给的参数outfun
是:
x
-当前迭代算法计算得到的点
optimValues
-结构,包含来自当前迭代的数据
示例使用以下字段optimValues
:
optimValues.iteration
-当前迭代的次数
optimValues.fval
-当前目标函数值
optimValues.searchdirection
-现时搜寻方向
状态
-算法的当前状态(“init”
,“中断”
,“通路”
,或“完成”
)
有关这些参数的更多信息,请参见输出函数的语法。
为这个例子创建函数文件:
在MATLAB编辑器中打开一个新文件。
复制并粘贴以下代码到该文件:
函数[history,searchdir] = runfmincon %使用OUTFUN history设置共享变量。x = [];历史。fval= []; searchdir = []; % call optimization x0 = [-1 1]; options = optimoptions(@fmincon,'OutputFcn',@outfun,... 'Display','iter','Algorithm','active-set'); xsol = 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
将文件保存为runfmincon.m
在一个文件夹上的MATLAB路径。
要运行示例,请输入:
[history searchdir] = runfmincon;
这将在命令窗口中显示以下迭代输出。
马克斯线搜索方向一阶Iter F-count f (x)约束steplength导数最优过程0 3 1.8394 - 0.5不可行的起点1 6 1.85127 -0.09197 1 0.313 -0.117 0.109 0.300167 - 9.33 0.778 - 2 9 1黑森修改两次3 12 0.529835 0.9209 1 0.12 0.186965 -1.517 0.5 -0.224 0.13 0.232 - 4 16 5 19 0.0729085 0.3313 1 6月22日-0.121 - 0.054 0.0353323 - -0.03303 -0.0542 - 0.0271 7 25 28 0.0235504 9.031 0.0235566 -0.0271 - 0.00587 0.003184 - 1 8 e-08 1不平等(-0.0146 - 8.51 e-07活跃在选择。约束条件= 1e-06):上下限ineqlin ineqnonlin 1 2局部极小值满足约束条件。优化完成是因为目标函数在可行方向上是不递减的,要在最优公差的取值范围内,且约束满足约束公差的取值范围内。
输出历史
是一个包含两个字段的结构:
history =带字段的结构:x:[9×2 double] fval:[9×1 double]
的fval
字段包含目标函数值,这些值对应于计算得到的点的序列fmincon
:
历史。fvalans = 1.8394 1.8513 0.3002 0.5298 0.1870 0.0729 0.0353 0.0236 0.0236
这些是在带标题的列中的迭代输出中显示的相同值f (x)
。
的x
领域的历史
包含算法计算得到的点序列:
历史。xans = -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
这个例子显示了这个点序列的一个图,其中每个点都被它的迭代号标记。
最优点出现在第8次迭代时。注意,序列中的最后两个点非常接近,以至于它们重叠了。
第二个输出参数,searchdir
,包含搜索方向fmincon
在每一个迭代。搜索方向是从当前迭代计算的点指向下一个迭代计算的点的向量:
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