Main Content

目标和约束有一个共同的功能in Serial or Parallel, Problem-Based

This example shows how to avoid calling a function twice when it computes values for both the objective and the constraints using the problem-based approach. For the solver-based approach, seeObjective and Nonlinear Constraints in the Same Function.

You typically use such a function in a simulation. Solvers usually evaluate the objective and nonlinear constraint functions separately. This evaluation is wasteful when you use the same calculation for both results.

This example also shows the effect of parallel computation on solver speed. For time-consuming functions, computing in parallel can speed the solver, as can avoiding calling the time-consuming function repeatedly at the same point. Using both techniques together speeds the solver the most.

Create Time-Consuming Function That Computes Several Quantities

Thecomputeallfunction returns outputs that are part of the objective and nonlinear constraints.

typecomputeall
function [f1,c1] = computeall(x) c1 = norm(x)^2 - 1; f1 = 100*(x(2) - x(1)^2)^2 + (1 - x(1))^2; pause(1) % simulate expensive computation end

The function includes apause(1)statement to simulate a time-consuming function.

Create Optimization Variables

This problem uses a four-element optimization variable.

x = optimvar('x',4);

Convert Function Using'ReuseEvaluation'

Convert thecomputeallfunction to an optimization expression. To save time during the optimization, use the'ReuseEvaluation'name-value pair. To save time for the solver to determine the output expression sizes (this happens only once), set the'OutputSize'name-value pair to[1 1], indicating that bothfandcare scalar.

[f,c] = fcn2optimexpr(@computeall,x,'ReuseEvaluation',true,'OutputSize',[1 1]);

Create Objective, Constraint, and Problem

Create the objective function from thefexpression.

obj = f + 20*(x(3) - x(4)^2)^2 + 5*(1 - x(4))^2;

Create the nonlinear inequality constraint from thecexpression.

cons = c <= 0;

Create an optimization problem and include the objective and constraint.

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);

Solve Problem

Monitor the time it takes to solve the problem starting from the initial pointx0.x = [-1;1;1;2].

x0.x = [-1;1;1;2]; x0.x = x0.x/norm(x0.x);% Feasible initial pointtic [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. 
sol =struct with fields:x: [4×1 double]
fval = 0.7107
exitflag = OptimalSolution
output =struct with fields:iterations: 25 funcCount: 149 constrviolation: 0 stepsize: 1.2914e-07 algorithm: 'interior-point' firstorderopt: 4.0000e-07 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.↵↵↵↵Optimization completed: The relative first-order optimality measure, 2.909695e-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.↵↵' solver: 'fmincon'
time1 = toc
time1 = 149.9299

The number of seconds for the solution is just over the number of function evaluations, which indicates that the solver computed each evaluation only once.

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 149.93, and the number of evaluation points was 149.

If, instead, you do not callfcn2optimexprusing'ReuseEvaluation', then the solution time doubles.

[f2,c2] = fcn2optimexpr(@computeall,x,'ReuseEvaluation',false); 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. 
time2 = toc
time2 = 298.4493

Parallel Processing

如果你有一个并行计算工具箱™许可证,you can save even more time by computing in parallel. To do so, set options to use parallel processing, and callsolvewith options.

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. 
time3 = toc
time3 = 74.7043

Using parallel processing and'ReuseEvaluation'together provides a faster solution than using'ReuseEvaluation'alone. See how long it takes to solve the problem using parallel processing alone.

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. 
time4 = toc
time4 = 145.5278

Summary of Timing Results

Combine the timing results into one table.

timingtable = table([time1;time2;time3;time4],...'RowNames',["Reuse Serial";"No Reuse Serial";"Reuse Parallel";"No Reuse Parallel"])
timingtable=4×1 tableVar1 ______ Reuse Serial 149.93 No Reuse Serial 298.45 Reuse Parallel 74.704 No Reuse Parallel 145.53

For this problem, on a computer with a 6-core processor, computing in parallel takes about half the time of computing in serial, and computing with'ReuseEvaluation'takes about half the time of computing without'ReuseEvaluation'. Computing in parallel with'ReuseEvaluation'takes about a quarter of the time of computing in serial without'ReuseEvaluation'.

See Also

Related Topics