此示例显示如何避免使用基于Solver的方法计算目标和约束的值时两次调用函数。要避免使用基于问题的方法来调用函数两次,请参阅目标和约束在串行或并行,基于问题的共同函数。
您通常在模拟中使用这样的功能。求解器如粉刺
单独评估目标和非线性约束函数。当您对两个结果使用相同的计算时,此评估是浪费的。
为避免浪费时间,通过保留耗时计算值,仅在需要时才使用嵌套功能来评估目标和约束函数。这种方法避免使用全局变量,同时保留中间结果保留并在目标和约束函数之间共享它们。
笔记
因为途径GA.
(全局优化工具箱)调用非线性约束函数,该示例中的技术通常不会将呼叫数量减少对目标或约束函数。
例如,假设ComputeLeal.
是由目标函数和非线性约束函数调用的昂贵(耗时)功能。假设您要使用粉刺
作为您的优化器。
编写计算RosenBrock功能的一部分的函数F1
并包括非线性约束C1.
将解决方案保留在原点周围的半径1的磁盘中。rosenbrock的函数是
其中具有0处的独特最小值0(1,1)。看解决约束的非线性问题,基于求解器。
这个例子没有非线性平等约束,所以CEQ1 = []
。添加A.暂停(1)
模拟昂贵的计算的陈述。
功能[F1,C1,CEQ1] = ComputeLl(x)CEQ1 = [];C1 = x(1)^ 2 + x(2)^ 2 - 1;F1 = 100 *(x(2) - x(1)^ 2)^ 2 +(1-x(1))^ 2;暂停(1)%模拟昂贵的计算结尾
保存Computeleall.m.
作为MATLAB上的文件®小路。
假设客观函数是
y= 100(X2-X12)2+(1 -X1)2
+ 20 *(X3.-X4.2)2+ 5 *(1 -X4.)2。
ComputeLeal.
返回目标函数的第一部分。嵌入呼叫ComputeLeal.
在嵌套功能中:
功能[x,f,eflag,outpt] = runobjconstr(x0,optss)如果nargin == 1%没有选择选择= [];结尾xlast = [];%最后一个地方computeall被称为myf = [];%在xlast上使用目标myc = [];%用于非线性不等式约束myceq = [];%使用非线性平等约束有趣= @objfun;%目标函数,下面嵌套cfun = @constr;%约束函数,下面嵌套%叫Fmincon.[x,f,eflag,outpt] = fmincon(fun,x0,[],[],[],[],[],[],cfun,选择);功能y = objfun(x)如果〜isequal(x,xlast)%检查是否需要计算[myf,myc,myceq] = computeall(x);xlast = x;结尾%现在计算目标函数y = myf + 20 *(x(3) - x(4)^ 2)^ 2 + 5 *(1 - x(4))^ 2;结尾功能[C,CEQ] = CONST(x)如果〜isequal(x,xlast)%检查是否需要计算[myf,myc,myceq] = computeall(x);xlast = x;结尾%现在计算约束函数c = myc;%在这种情况下,计算是微不足道的CEQ = MYCEQ;结尾结尾
将嵌套函数保存为命名的文件runobjconstr.m.
在你的matlab路径上。
运行函数,定时呼叫Tic.
和TOC.
。
选择= Optimoptions(@Fmincon,'算法'那'内点'那'展示'那'离开');x0 = [-1,1,1,2];TIC [x,fval,ExitFlag,输出] = runobjconstr(x0,opts);TOC.
经过时间为259.364090秒。
比较时间以使用嵌套功能运行求解器。为没有嵌套功能的运行,保存myrosen3.m.
作为目标函数文件和约束
作为约束。
功能y = myrosen2(x)f1 = computeall(x);%获得目标的第一部分Y = F1 + 20 *(x(3) - x(4)^ 2)^ 2 + 5 *(1 - x(4))^ 2;结尾功能[c,ceq] = contrure(x)[〜,c,ceq] = computeall(x);结尾
跑步粉刺
,时间来调用Tic.
和TOC.
。
TIC [x,fval,ExitFlag,输出] = Fmincon(@ myrosen2,x0,......[],[],[],[],[],[],@ contr,Opts);TOC.
经过时间为518.364770秒。
求解器只要以前需要两倍,因为它分别评估目标和约束。
如果您有一个并行计算工具箱™许可证,可以通过设置设置更多时间使用指α.
选择真的
。
parpool.
使用“本地”配置文件启动并行池(Parpool)连接到并行池(工人数:6)。ANS = ProcessPool具有属性:Connected:True NumWorkers:6群集:本地连接文件:{} autoaddclientPath:true idledimeout:30分钟(剩余30分钟)spmded:true
选择= Optimoptions(选择,'使用指平行',真的);TIC [x,fval,ExitFlag,输出] = runobjconstr(x0,opts);TOC.
经过时间为121.151203秒。
在这种情况下,与嵌套功能的串行运行相比,使并行计算将计算时间减少为一半。
将运行与并行计算的运行进行比较,有嵌套功能:
TIC [x,fval,ExitFlag,输出] = Fmincon(@ myrosen2,x0,......[],[],[],[],[],[],@ contr,Opts);TOC.
经过时间为235.914597秒。
在此示例中,并行计算但未嵌套计算机需要大约与计算嵌套但不行的相同时间。计算嵌套和并行两者都需要单独使用的一半。