Main Content

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

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

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

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

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

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],表示 fc 都是标量。

[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 进行串行计算的四分之一。

另请参阅

相关主题