主要内容

目标和约束具有串行或并行的共同功能,基于问题的

这个示例展示了如何在使用基于问题的方法同时计算目标和约束的值时避免调用函数两次。有关基于求解器的方法,请参见同一函数中的客观约束与非线性约束

您通常在模拟中使用这样的函数。求解器通常分别求解目标函数和非线性约束函数。当对两个结果使用相同的计算时,这种计算是浪费的。

本例还说明了并行计算对求解速度的影响。对于耗时的函数,并行计算可以加快求解器的速度,避免在同一点重复调用耗时的函数。同时使用这两种技术可以提高求解速度。

创建计算几个量的耗时函数

computeall函数返回的输出是目标和非线性约束的一部分。

类型computeall
函数[f1,c1] = computeall(x) c1 = norm(x)^2 - 1;f1 = 100 * (x (2) - (1) ^ 2) ^ 2 + (1 - x (1)) ^ 2 + besselj (1, x (1));暂停(1)%模拟昂贵的计算结束

该函数包含暂停(1)语句来模拟耗时的函数。

创建优化变量

这个问题使用了一个四元素优化变量。

X = optimvar(“x”4);

使用转换函数ReuseEvaluation

转换computeall函数转换为优化表达式。为节省优化期间的时间,请使用ReuseEvaluation名称-值参数。为节省求解器确定输出表达式大小的时间(这种情况只发生一次),请设置OutputSize参数的名称-值[1],表明两者f而且c是标量。

[f,c] = fcn2optimexpr(@computeall,x,“ReuseEvaluation”,真的,“OutputSize”[1]);

创建目标、约束和问题

创建目标函数f表达式。

Obj = f + 20*(x(3) - x(4)²)²+ 5*(1 - x(4))²;

创建非线性不等式约束c表达式。

Cons = c <= 0;

创建一个优化问题,包括目标和约束条件。

问题=优化问题(“目标”、obj);probo . constraints .cons = cons;显示(概率)
OptimizationProblem:解:x最小化:((长度+(20。* x (x(3) -(4) ^ 2)。^ 2))+(5。* (1 - x(4)) ^ 2))地点:[长度~]= computeall (x);where: [~,arg_LHS] = computeall(x);

解决问题

从初始点开始,监控解决问题所需的时间x0。X = [-1;1;1;2]

x0。X = [-1;1;1;2];x0。X = xx . X /norm(xx . X);%可行起始点Tic [sol,fval,exitflag,output] = solve(prob,x0)
使用fmincon解决问题。找到满足约束条件的局部最小值。优化完成是因为目标函数在可行方向上不递减,在最优性容差值范围内,约束条件满足在约束容差值范围内。<停止条件详细信息>
索尔=带字段的结构:X: [4×1 double]
Fval = 0.9091
exitflag = OptimalSolution
输出=带字段的结构:迭代:24 funcCount: 142 constrviolation: 0步长:2.6813e-05算法:'内部点' firstorderopt: 1.0143e-06 cgiterations: 7消息:'局部最小值发现满足约束。(()优化完成,因为目标函数在()可行方向上不下降,直到最优性公差的值之内,()且约束条件满足到约束公差的值之内。(() <停止条件详细信息>()完成优化:相对一阶优化度量,8.264724e-07,()小于选项。OptimalityTolerance = 1.000000e-06,相对最大约束(违例)为0.000000e+00,小于选项。约束容忍= 1.000000e-06。' best可行:[1×1 struct] objectivederivative: "有限差分" constraintderivative: "有限差分"求解器:'fmincon'
Time1 = toc
Time1 = 144.0930

求解的秒数刚好超过函数求值的次数,这表明求解器只计算一次每个求值。

流(“解决的秒数为%g,评估点的数量为%g。\n”、time1 output.funcCount)
求解秒数为144.093,评估点数为142。

相反,如果你不打电话fcn2optimexpr使用ReuseEvaluation,则解时间加倍。

[f2,c2] = fcn2optimexpr(@computeall,x,“ReuseEvaluation”假的,“分析”“关闭”);methoda = f2 + 20 * x (x (3) - (4) ^ 2) ^ 2 + 5 * (1 - x (4)) ^ 2;con2 = c2 <= 0;Prob2 =优化问题(“目标”, methoda);prob2.Constraints。con2 = con2;Tic [sol2,fval2,exitflag2,output2] = solve(prob2,x0);
使用fmincon解决问题。找到满足约束条件的局部最小值。优化完成是因为目标函数在可行方向上不递减,在最优性容差值范围内,约束条件满足在约束容差值范围内。<停止条件详细信息>
Time2 = toc
Time2 = 286.3669

并行处理

如果您拥有并行计算工具箱™许可证,则可以通过并行计算节省更多时间。为此,将选项设置为使用并行处理,并调用解决与选择。

选项= optimoptions(问题,“UseParallel”,真正的);Tic [sol3,fval3,exitflag3,output3] = solve(prob,x0,“选项”、选择);
使用fmincon解决问题。找到满足约束条件的局部最小值。优化完成是因为目标函数在可行方向上不递减,在最优性容差值范围内,约束条件满足在约束容差值范围内。<停止条件详细信息>
Time3 = toc
Time3 = 72.1202

使用并行处理和ReuseEvaluation一起提供了比单独使用更快的解决方案ReuseEvaluation一个人。看看单独使用并行处理解决问题需要多长时间。

Tic [sol4,fval4,exitflag4,output4] = solve(prob2,x0,“选项”、选择);
使用fmincon解决问题。找到满足约束条件的局部最小值。优化完成是因为目标函数在可行方向上不递减,在最优性容差值范围内,约束条件满足在约束容差值范围内。<停止条件详细信息>
Time4 = toc
Time4 = 136.8033

计时结果汇总

将计时结果合并到一个表中。

Timingtable = table([time1;time2;time3;time4],...“RowNames”, (“串行重用”“不可重复使用系列”“重用平行”“无重用并行”])
timingtable =4×1表Var1 ______复用串行144.09无复用串行286.37复用并行72.12无复用并行136.8

对于这个问题,在具有6核处理器的计算机上,并行计算所花费的时间大约是串行计算的一半ReuseEvaluation大约需要一半的计算时间没有ReuseEvaluation.并行计算ReuseEvaluation大约需要串行计算的四分之一的时间ReuseEvaluation

另请参阅

相关的话题