GlobalSearch 和 MultiStart 的绘图函数
什么是绘图函数?
PlotFcn
的 options
字段指定优化函数在每次迭代时调用的一个或多个函数。绘图函数绘制算法执行时各种进度指标。传递函数句柄或函数句柄元胞数组。绘图函数的结构体与输出函数的结构体相同。有关此结构体的详细信息,请参阅OutputFcn。
绘图函数是专门的输出函数(请参阅GlobalSearch 和 MultiStart 的输出函数)。有两个预定义的绘图函数:
@gsplotbestf
绘制最佳目标函数值。@gsplotfunccount
绘制函数计算的次数。
绘图函数窗口有暂停和停止按钮。默认情况下,所有图表都会出现在一个窗口中。
要使用全局绘图函数:
使用 OutputFcn 中描述的语法编写绘图函数。
将
GlobalSearch
或MultiStart
对象的PlotFcn
属性设置为绘图函数的函数句柄。您可以通过将PlotFcn
属性设置为函数句柄的元胞数组来使用多个绘图函数。
注意
绘图函数不支持 subplot
语句,因为绘图函数框架管理轴。要指定多个子图,请编写单独的绘图函数,并将其作为元胞数组传递给求解器:
options = optimoptions("solvername",PlotFcn={@plot1,@plot2,@plot3});
输出函数支持 subplot
,因此您可以使用输出函数代替绘图函数,在一个函数中包含多个绘图。
内置绘图函数的详细信息
内置的绘图函数具有令您惊讶的特性。
@gsplotbestf
可以有非严格减少的图。这是因为早期值可能由具有负退出标志(例如不可行的解)的局部求解器运行产生。即使其函数值更高,具有正退出标志的后续局部解也更好。一旦局部求解器返回具有正退出标志的值,则图会单调递减。@gsplotfunccount
可能不会绘制函数计算的总数。这是因为GlobalSearch
在最后一次调用绘图函数后可以继续执行函数计算。有关详细信息,请参阅GlobalSearch 算法。
MultiStart
绘图函数
此示例绘制了获得 MultiStart
的更佳局部最小值所需的局部求解器运行次数。该示例还使用内置的绘图函数来显示当前最佳函数值。
示例问题与 寻找全局或多个局部最小值 相同,但增加了边界。
该示例使用持久变量来存储以前的最佳值。绘图函数检查每次局部求解器运行后的最佳函数值,该值可在 bestfval
结构体的 optimValues
字段中找到。如果该值不低于之前的最佳值,绘图函数将没有改进的连续调用次数加 1,并绘制条形图。如果该值低于之前的最佳值,绘图函数会在图表中以值 1 开始一个新条形图。在绘图之前,绘图函数对连续调用的次数取对数。对数有助于使图表清晰易读,因为有些值可能比其他值大得多。
要使用嵌套函数而不是持久变量来存储局部结果,请参阅 嵌套输出函数的示例。
绘图函数示例
此示例最小化了 sawtoothxy
辅助函数,该函数列在本示例末尾。一般来说,将您的目标函数保存在 MATLAB® 路径上的文件中。
NumberToNextBest
自定义绘图函数附加到此示例。一般来说,将您的绘图函数保存在 MATLAB 路径上的文件中。下面是一份列表。
type NumberToNextBest
function stop = NumberToNextBest(optimValues, state) persistent bestfv bestcounter stop = false; switch state case 'init' % Initialize variable to record best function value. bestfv = []; % Initialize counter to record number of % local solver runs to find next best minimum. bestcounter = 1; % Create the histogram. bar(log(bestcounter),'tag','NumberToNextBest'); xlabel('Number of New Best Fval Found'); ylabel('Log Number of Local Solver Runs'); title('Number of Local Solver Runs to Find Lower Minimum') case 'iter' % Find the axes containing the histogram. NumToNext = ... findobj(get(gca,'Children'),'Tag','NumberToNextBest'); % Update the counter that records number of local % solver runs to find next best minimum. if ~isequal(optimValues.bestfval, bestfv) bestfv = optimValues.bestfval; bestcounter = [bestcounter 1]; else bestcounter(end) = bestcounter(end) + 1; end % Update the histogram. set(NumToNext,'Ydata',log(bestcounter)) end
创建问题结构体和全局求解器对象。设置 [-3e3,-4e3]
的下界、[4e3,3e3]
的上界,并设置全局求解器使用 NumberToNextBest
自定义绘图函数和 gsplotbestf
内置绘图函数。
problem = createOptimProblem('fmincon',... 'objective',@(x)sawtoothxy(x(1),x(2)),... 'x0',[100,-50],'lb',[-3e3 -4e3],... 'ub',[4e3,3e3],'options',... optimoptions(@fmincon,'Algorithm','sqp')); ms = MultiStart('PlotFcn',{@NumberToNextBest,@gsplotbestf});
运行全局求解器,进行 100 次局部求解器运行。
rng(2); % For reproducibility
[x,fv] = run(ms,problem,100);
MultiStart completed some of the runs from the start points. 34 out of 100 local solver runs converged with a positive local solver exitflag.
辅助函数
以下代码创建 sawtoothxy
辅助函数。
function f = sawtoothxy(x,y) [t,r] = cart2pol(x,y); % change to polar coordinates h = cos(2*t - 1/2)/2 + cos(t) + 2; g = (sin(r) - sin(2*r)/2 + sin(3*r)/3 - sin(4*r)/4 + 4) ... .*r.^2./(r+1); f = g.*h; end
无平行绘图函数
虽然 MultiStart
可以并行运行,但它不支持全局输出函数和并行绘图函数。此外,虽然 MultiStart
并行运行时局部输出函数和绘图函数在工作进程上运行,但其效果与串行运行不同。本地输出和绘图函数在工作进程上运行时不会创建显示。在工作进程将其结果传递给客户端(MultiStart
并行作业的发起者)之前,您看不到输出和绘图函数的任何其他效果。
有关并行运行 MultiStart
的信息,请参阅 并行计算。