具有串行或并行共同函数的目标和约束,基于问题
此示例展示了如何使用基于问题的方法计算目标和约束的值时避免两次调用函数。有关基于求解器的方法,请参阅同一函数中的目标和非线性约束。
您通常在模拟中使用这样的函数。求解器通常分别评估目标和非线性约束函数。当对两个结果使用相同的计算时,这种评估是浪费的。
这个示例还展示了并行计算对求解器速度的影响。对于耗时函数,并行计算可以加快求解器的速度,并避免在同一点重复调用耗时函数。同时使用这两种技术可以最大程度地提高求解器速度。
创建计算多个量的耗时函数
computeall
函数返回作为目标和非线性约束的一部分的输出。
type computeall
function [f1,c1] = computeall(x) c1 = norm(x)^2 - 1; f1 = 100*(x(2) - x(1)^2)^2 + (1 - x(1))^2 + besselj(1,x(1)); pause(1) % simulate expensive computation end
函数中包含一个 pause(1)
语句来模拟耗时函数。
创建优化变量
该问题使用四元素优化变量。
x = optimvar('x',4);
使用 ReuseEvaluation
转换函数
将 computeall
函数转换为优化表达式。为了节省优化时间,请使用 ReuseEvaluation
name-value 参量。为了节省求解器确定输出表达式大小的时间(这只会发生一次),将 OutputSize
名称值参量设置为 [1 1]
,表示 f
和 c
都是标量。
[f,c] = fcn2optimexpr(@computeall,x,'ReuseEvaluation',true,'OutputSize',[1 1]);
创建目标、约束和问题
从 f
表达式创建目标函数。
obj = f + 20*(x(3) - x(4)^2)^2 + 5*(1 - x(4))^2;
从 c
表达式创建非线性不等式约束。
cons = c <= 0;
创建一个优化问题并包括目标和约束。
prob = optimproblem('Objective',obj);
prob.Constraints.cons = cons;
show(prob)
OptimizationProblem : Solve for: x minimize : ((arg3 + (20 .* (x(3) - x(4).^2).^2)) + (5 .* (1 - x(4)).^2)) where: [arg3,~] = computeall(x); subject to cons: arg_LHS <= 0 where: [~,arg_LHS] = computeall(x);
求解问题
监控从初始点 x0.x = [-1;1;1;2]
开始求解问题所需的时间。
x0.x = [-1;1;1;2];
x0.x = x0.x/norm(x0.x); % Feasible initial point
tic
[sol,fval,exitflag,output] = solve(prob,x0)
Solving problem using fmincon. 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. <stopping criteria details>
sol = struct with fields:
x: [4×1 double]
fval = 0.9091
exitflag = OptimalSolution
output = struct with fields:
iterations: 24
funcCount: 142
constrviolation: 0
stepsize: 2.6813e-05
algorithm: 'interior-point'
firstorderopt: 1.0143e-06
cgiterations: 7
message: '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.↵↵<stopping criteria details>↵↵Optimization completed: The relative first-order optimality measure, 8.264724e-07,↵is less than options.OptimalityTolerance = 1.000000e-06, and the relative maximum constraint↵violation, 0.000000e+00, is less than options.ConstraintTolerance = 1.000000e-06.'
bestfeasible: [1×1 struct]
objectivederivative: "finite-differences"
constraintderivative: "finite-differences"
solver: 'fmincon'
time1 = toc
time1 = 144.0930
解所需的秒数刚好超过函数计算的次数,这表明求解器仅计算一次每个评估。
fprintf("The number of seconds to solve was %g, and the number of evaluation points was %g.\n",time1,output.funcCount)
The number of seconds to solve was 144.093, and the number of evaluation points was 142.
相反,如果您不使用 ReuseEvaluation
调用 fcn2optimexpr
,则解时间将会加倍。
[f2,c2] = fcn2optimexpr(@computeall,x,'ReuseEvaluation',false,'Analysis','off'); obj2 = f2 + 20*(x(3) - x(4)^2)^2 + 5*(1 - x(4))^2; cons2 = c2 <= 0; prob2 = optimproblem('Objective',obj2); prob2.Constraints.cons2 = cons2; tic [sol2,fval2,exitflag2,output2] = solve(prob2,x0);
Solving problem using fmincon. 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. <stopping criteria details>
time2 = toc
time2 = 286.3669
并行处理
如果您拥有 Parallel Computing Toolbox ™ 许可证,您可以通过并行计算节省更多时间。为此,请设置选项以使用并行处理,并使用选项调用 solve
。
options = optimoptions(prob,'UseParallel',true); tic [sol3,fval3,exitflag3,output3] = solve(prob,x0,'Options',options);
Solving problem using fmincon. 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. <stopping criteria details>
time3 = toc
time3 = 72.1202
与单独使用 ReuseEvaluation
相比,使用并行处理和 ReuseEvaluation
可以提供更快的解。看看仅使用并行处理求解问题需要多长时间。
tic
[sol4,fval4,exitflag4,output4] = solve(prob2,x0,'Options',options);
Solving problem using fmincon. 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. <stopping criteria details>
time4 = toc
time4 = 136.8033
计时结果汇总
将计时结果合并到一张表中。
timingtable = table([time1;time2;time3;time4],... 'RowNames',["Reuse Serial";"No Reuse Serial";"Reuse Parallel";"No Reuse Parallel"])
timingtable=4×1 table
Var1
______
Reuse Serial 144.09
No Reuse Serial 286.37
Reuse Parallel 72.12
No Reuse Parallel 136.8
对于该问题,在具有 6 核处理器的计算机上,并行计算所花的时间约为串行计算的一半,使用 ReuseEvaluation
进行计算所花的时间约为不使用 ReuseEvaluation
进行计算的一半。使用 ReuseEvaluation
进行并行计算所需的时间大约是不使用 ReuseEvaluation
进行串行计算的四分之一。