Main Content

创建 for 循环进行静态分析

考虑在导体中放置 20 个电子的问题(请参阅 使用优化变量的约束静电非线性优化)。电子以最小化其总势能的方式排列,但受到位于体内的约束。本例重点讲解了势能,它自然地表示为嵌套的 for 循环,以及如何转换 for 循环来执行静态分析。

无需修改即可创建静态分析问题

对于 N = 20 个电子,创建问题和优化变量。

N = 20;
x = optimvar("x",N,LowerBound=-1,UpperBound=1);
y = optimvar("y",N,LowerBound=-1,UpperBound=1);
z = optimvar("z",N,LowerBound=-2,UpperBound=0);
elecprob = optimproblem;

导电体有以下约束。

elecprob.Constraints.spherec = (x.^2 + y.^2 + (z+1).^2) <= 1;
elecprob.Constraints.plane1 = z <= -x-y;
elecprob.Constraints.plane2 = z <= -x+y;
elecprob.Constraints.plane3 = z <= x-y;
elecprob.Constraints.plane4 = z <= x+y;

目标函数是系统的势能,它是每个电子对的距离倒数的总和:

energy=i<j1electron(i)-electron(j).

将目标函数定义为优化表达式。

energy = optimexpr;
for ii = 1:(N-1)
    for jj = (ii+1):N
        energy = energy + ((x(ii) - x(jj))^2 + (y(ii) - y(jj))^2 + (z(ii) - z(jj))^2)^(-1/2);
    end
end
elecprob.Objective = energy;

从以 [0,0,-1] 为中心、半径为 1/2 的球体上随机分布的电子开始优化。

rng default % For reproducibility
x0 = randn(N,3);
for ii=1:N
    x0(ii,:) = x0(ii,:)/norm(x0(ii,:))/2;
    x0(ii,3) = x0(ii,3) - 1;
end
init.x = x0(:,1);
init.y = x0(:,2);
init.z = x0(:,3);

通过调用 solve 求解问题。对解进行计时。

tic
[sol,fval,exitflag,output] = solve(elecprob,init)
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: [20×1 double]
    y: [20×1 double]
    z: [20×1 double]

fval = 163.0099
exitflag = 
    OptimalSolution

output = struct with fields:
              iterations: 94
               funcCount: 150
         constrviolation: 0
                stepsize: 2.8395e-05
               algorithm: 'interior-point'
           firstorderopt: 8.1308e-06
            cgiterations: 0
                 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.090884e-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: "reverse-AD"
    constraintderivative: "closed-form"
                  solver: 'fmincon'

toc
Elapsed time is 14.483005 seconds.

解时间超过 10 秒(您的结果可能会有所不同)。

修改问题以实现高效静态分析

该视频演示了这些步骤。

为了使优化表达式更有效地工作,提取 for 循环并将其转换为局部函数。首先,选择从 energy = optimexpr; 到最后的 end 的代码行。然后,右键单击选定的代码行并选择转换为本地函数

loop_selected.png

converttolocal.png

编辑结果函数(出现在本示例末尾)如下:

  • 将函数名称更改为 myenergy

  • 编辑第一行代码如下:

energy = function myenergy(N, x, y, z);
  • 在第二行代码中,将初始值从 optimexpr 更改为 0。

为了利用静态分析,通过调用 fcn2optimexpr 将能量作为目标函数放入问题中。

energy = fcn2optimexpr(@myenergy,N,x,y,z);
elecprob.Objective = energy;

通过调用 solve 求解问题。对解进行计时。

tic
[sol,fval,exitflag,output] = solve(elecprob,init)
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: [20×1 double]
    y: [20×1 double]
    z: [20×1 double]

fval = 163.0099
exitflag = 
    OptimalSolution

output = struct with fields:
              iterations: 94
               funcCount: 150
         constrviolation: 0
                stepsize: 2.8395e-05
               algorithm: 'interior-point'
           firstorderopt: 8.1308e-06
            cgiterations: 0
                 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.090884e-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: "reverse-AD"
    constraintderivative: "closed-form"
                  solver: 'fmincon'

toc
Elapsed time is 0.686725 seconds.

解时间大大减少,降至一秒以下。

与无分析进行比较

您还可以通过将目标函数视为黑匣子来求解问题。黑箱目标不能利用自动微分,因此求解器必须采取有限差分步骤来估计目标梯度。然而,当底层函数能够快速评估时,黑盒就可以快速运行。比较设置 fcn2optimexpr 创建黑盒目标时的解时间。

energy = fcn2optimexpr(@myenergy,N,x,y,z,Analysis="off");
elecprob.Objective = energy;
tic
[sol,fval] = solve(elecprob,init)
Solving problem using fmincon.

Solver stopped prematurely.

fmincon stopped because it exceeded the function evaluation limit,
options.MaxFunctionEvaluations = 3.000000e+03.
sol = struct with fields:
    x: [20×1 double]
    y: [20×1 double]
    z: [20×1 double]

fval = 163.3769
toc
Elapsed time is 0.392945 seconds.

求解器未完成优化,因为它超出了函数评估限制。此外,得到的 fval 比前两个解更高。增加函数评估限制并重试。

opts = optimoptions("fmincon",MaxFunctionEvaluations=1e4);
tic
[sol,fval,exitflag,output] = solve(elecprob,init,Options=opts)
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: [20×1 double]
    y: [20×1 double]
    z: [20×1 double]

fval = 163.0099
exitflag = 
    OptimalSolution

output = struct with fields:
              iterations: 96
               funcCount: 5978
         constrviolation: 0
                stepsize: 5.5563e-06
               algorithm: 'interior-point'
           firstorderopt: 6.9362e-06
            cgiterations: 0
                 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, 6.902142e-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: "closed-form"
                  solver: 'fmincon'

toc
Elapsed time is 0.603105 seconds.

解时间与静态分析大致相同,目标函数值也是如此。output 结构表明求解器采用有限差分步骤来估计目标梯度。求解器需要进行数千次函数计算,而之前的情况只需要进行少于 200 次。如果您的函数评估很耗时,则这种方法可能效率低下。

总结

有时,您可以通过转换 for 循环进行静态分析来节省解时间。将 for 循环转换为函数相当简单:突出显示循环,右键单击以显示上下文菜单,选择创建局部函数或函数文件的选项,然后对新函数进行微小编辑。

无论如何,使用 fcn2optimexprfor 循环表达式放入您的问题中。这种做法使您能够自动获得静态分析的任何未来改进,而无需重写代码。

辅助函数

以下代码创建 myenergy 辅助函数。

function energy = myenergy(N, x, y, z)
energy = 0;
for ii = 1:(N-1)
    for jj = (ii+1):N
        energy = energy + ((x(ii) - x(jj))^2 + (y(ii) - y(jj))^2 + (z(ii) - z(jj))^2)^(-1/2);
    end
end
end

另请参阅

相关主题