创建有效的优化问题
当线性问题有整数约束时,解决
调用intlinprog
获取解决方案。有关获得更快的解或更多整数可行点的建议,请参见整型线性规划调优.
在开始解决问题之前,有时可以改进问题约束或目标的表述。通常,软件可以以向量化的方式更快地为目标函数或约束创建表达式,而不是以循环的方式。当一个优化表达式受制于自动微分时,这种速度差异尤其大;看到优化工具箱中的自动区分.
通常,通过将其编写为单独的函数更容易创建一个有效的循环,如为静态分析创建for循环.在本例中,创建包含函数的优化表达式fcn2optimexpr
,详见优化表达式的静态分析.
假设目标函数是
在哪里x
,b
而且c
是优化变量。该目标函数的一般表述方法如下:
使用一个
为
循环。x = optimvar (“x”、30、30、10);b = optimvar (“b”10);c = optimvar (“c”、30、30);Tic expr = optimexpr;为i = 1:30为j = 1:30为K = 1:10 expr = expr + x(i,j, K)*b(K)*c(i,j);结束结束结束toc
运行时间为307.459465秒。
在这里,
expr
包含目标函数表达式。为了让软件有效地计算这个表达式,把它写成一个单独的函数:函数Expr = loopme(x,b,c) = 0;倪=大小(x, 1);新泽西=大小(x, 2);nk =大小(x, 3);为我= 1:倪为j = 1:新泽西为K = 1:nk expr = expr + x(i,j, K)*b(K)*c(i,j);结束结束结束结束
包括using的表达式
fcn2optimexpr
.(@loopme,x,b,c,OutputSize=[1,1]);toc
运行时间为23.888763秒。
在问题中包含目标函数。
问题= optimproblem (“客观”, expr);
使用向量化语句。向量化语句通常比类语句运行得快
为
未被修改用于静态分析的循环。可以通过几种方式创建向量化语句。扩大
b
而且c
.要启用术语相乘,请创建大小与相同的常量x
.Tic bigb =重塑(b,1,1,10);bigb = repmat (bigb, 30岁,30岁,1);bigc = repmat (c, 1, 1, 10);expr =总和(和(和(x。* bigb。* bigc)));toc
运行时间为0.013631秒。
循环一次
b
.Tic expr = optimexpr;为k = 1:10 expr = expr +笔(金额(x (:,:, k)。* c)) * b (k);结束toc
运行时间为0.044985秒。
通过遍历创建一个表达式
b
然后对循环后的项求和。Tic expr = optimexpr(30,30,10);为K = 1:10 expr(:,:, K) = x(:,:, K).*c*b(K);结束expr =总和(expr (:));toc
运行时间为0.039518秒。
观察该示例的向量化和非向量化实现之间的速度差异基于优化变量的约束静电非线性优化.本例使用R2020b中的自动区分计时。
N = 30;x = optimvar (“x”N下界的, 1“UpperBound”1);y = optimvar (“y”N下界的, 1“UpperBound”1);z = optimvar (“z”N下界的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;rng默认的%的再现性x0 = randn (N, 3);为ii=1:N x0(ii,:) = x0(ii,:)/norm(x0(ii,:))/2;X0 (ii,3) = X0 (ii,3) - 1;结束init。x=x0(:,1); init.y = x0(:,2); init.z = x0(:,3); opts = optimoptions(“fmincon”,“显示”,“关闭”);Tic能量= optimexpr(1);为ii = 1:(N-1) jj = (ii+1):N;%矢量化Tempe = (x(ii) - x(jj))。²+ (y(ii) - y(jj))^2 + (z(ii) - z(jj)).^2;能量=能量+ sum(tempe.^(-1/2));结束elecprob。目标=能量;disp (的矢量化计算时间:[sol,fval,exitflag,output] = solve(elecprob,init,)“选项”、选择);toc
向量化计算时间:运行时间为1.838136秒。
Tic energy2 = optimexpr(1);%用于非向量化比较为2 = 1: (n - 1)为jjj = (2 + 1): N;%不矢量化energy2 = energy2 + (x (x (2) - (jjj)) ^ 2 + (y (ii) - y (jjj)) ^ 2 + (z (ii) - z (jjj)) ^ 2) ^ (1/2);结束结束elecprob。目标= energy2;disp (“Non-vectorized计算时间:[sol,fval,exitflag,output] = solve(elecprob,init,)“选项”、选择);toc
非向量化计算时间:运行时间为204.615210秒。
向量化版本大约比非向量化版本快100倍。
与静态分析版本比较。的代码myenergy
函数出现在本例的末尾。
elecprob。目标= fcn2optimexpr (@myenergy, N, x, y, z);
通过打电话来解决问题解决
.时间的解决方案。
disp (“静态分析计算时间:”tic [sol,fval,exitflag,output] = solve(elecprob,init,)“选项”、选择);toc
静态分析计算时间:运行时间为1.293513秒。
静态分析的计算时间最短。
此代码创建myenergy
函数。
函数energy = myenergy(N, x, y, z)为2 = 1: (n - 1)为jj = (2 + 1): N =能源+ (x (x (2) - (jj)) ^ 2 + (y (ii) - y (jj)) ^ 2 + (z (ii) - z (jj)) ^ 2) ^ (1/2);结束结束结束