主要内容

创建高效的优化问题

当一个线性问题整数约束,解决调用intlinprog获得解决方案。建议获得更快的解决方案或更多integer-feasible点,看到的调优整数线性规划

在开始之前解决问题,有时你可以改善你的问题制定的约束或目标。通常,软件可以更快地为目标函数或约束创建表达式矢量化的方式,而不是在一个循环中。这个速度差异尤其当表达式是一个优化问题自动分化;看到自动微分优化工具箱

通常,更容易建立一个有效的循环通过编写它作为一个单独的函数,描述的创建静态分析的for循环。在这种情况下,创建包含函数的表达式优化利用fcn2optimexpr解释说,静态分析的优化表达式

假设你的目标函数

= 1 30. j = 1 30. k = 1 10 x , j , k b k c , j ,

在哪里x,bc是优化变量。两种通用的方式来制定这个目标函数如下:

  • 使用一个循环。

    x = optimvar (“x”、30、30、10);b = optimvar (“b”10);c = optimvar (“c”、30、30);抽搐expr = optimexpr;i = 1:30j = 1:30k = 1:10 expr = expr + x (i, j, k) * b (k) * c (i, j);结束结束结束toc
    运行时间是307.459465秒。

    在这里,expr包含目标函数表达式。软件有效地评估这个表达式,把它写成一个单独的功能:

    函数expr = loopme (x、b、c) expr = 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);结束结束结束结束

    包括表达式使用fcn2optimexpr

    抽搐expr = fcn2optimexpr (@loopme x、b、c、OutputSize = [1]);toc
    运行时间是23.888763秒。

    包括问题的目标函数。

    问题= optimproblem (“客观”,expr);
  • 使用矢量化语句。矢量化语句通常比一个跑得更快为静态分析回路,没有被修改。您可以创建一个矢量化语句在几个方面。

    • 扩大bc。使term-wise乘法,创建常量,是相同的大小x

      抽搐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

      抽搐expr = optimexpr;k = 1:10 expr = expr +笔(金额(x (:,:, k)。* c)) * b (k);结束toc
      运行时间是0.044985秒。
    • 创建一个表达式,循环结束b然后求和项后循环。

      抽搐expr = optimexpr (30、30、10);k = 1:10 expr (:,:, k) = x (:,:, k)。* c * b (k);结束expr =总和(expr (:));toc
      运行时间是0.039518秒。

观察矢量之间的速度差和nonvectorized实现的例子静电约束非线性优化使用优化变量。这个例子是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。y ^ 2 +。^ 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);2 = 1:N x0 (ii):) = x0 (ii):) /规范(x0 (ii):)) / 2;x0 (2, 3) = x0 (ii, 3) - 1;结束init。x=x0(:,1); init.y = x0(:,2); init.z = x0(:,3); opts = optimoptions(“fmincon”,“显示”,“关闭”);抽搐的能量= optimexpr (1);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));结束elecprob。目标=能量;disp (的矢量化计算时间:)[溶胶、fval exitflag、输出]=解决(elecprob init,“选项”、选择);toc
矢量化计算时间:运行时间是1.838136秒。
抽搐energy2 = optimexpr (1);%为nonvectorized比较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计算时间:)[溶胶、fval exitflag、输出]=解决(elecprob init,“选项”、选择);toc
Non-vectorized计算时间:运行时间是204.615210秒。

矢量化的版本是100倍nonvectorized版本。

比较静态分析版本。的代码myenergy函数出现在这个例子的结束。

elecprob。目标= fcn2optimexpr (@myenergy, N, x, y, z);

通过调用解决问题解决。时间的解决方案。

disp (的静态分析计算时间:)抽搐(溶胶,fval、exitflag、输出)=解决(elecprob init,“选项”、选择);toc
静态分析计算时间:运行时间是1.293513秒。

静态分析提供最低的计算时间。

这段代码创建了myenergy函数。

函数能量= myenergy (N, x, y, z)能源= 0;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);结束结束结束

相关的话题