优化算法之D.S.C法与D.S.C-Powell法及其C++代码实现

2023-12-16 10:32

本文主要是介绍优化算法之D.S.C法与D.S.C-Powell法及其C++代码实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

优化算法之D.S.C法与D.S.C-Powell法

    • 一、凸函数
    • 二、二次插值法
    • 三、D.S.C法
    • 四、D.S.C-Powell法
    • 五、实验结果
    • 六、C++源码


注:本文内容大多借鉴于《最优计算方法》——陈开周
注:本文讨论的优化函数只限于二维。


一、凸函数

在介绍这两个算法之前,我们需要先了解一下凸函数的概念。因为大多数传统的优化算法所求的函数模型都是默认为凸函数,这两个算法也不例外,而对于其他的复杂函数,目前比较流行的解决办法是使用进化算法,本文将只讨论D.S.C法与D.S.C-Powell法。
所谓凸函数,用一句话来概括就是弦值大于弧值的函数,也就是在一个函数上任取两点,这两点连成一条弦,然后在这两点对应的横坐标之间再任取一点,该点对应在弦上的值永远比对应在函数上的值大,下面的图很好的展示了这一特征:
在这里插入图片描述
如上图所示,在凸函数中,对于函数f(x),任意a,b∈R,c∈(a,b)或(b,a),g(x)是过(a,f(a))与(b,f(b))的一条直线,则g( c ) > f( c )。下面给出一些不是凸函数的示例:
在这里插入图片描述
在这里插入图片描述

二、二次插值法

对于我们要谈到的两种算法除了要了解凸函数外,我们还需要知道二次插值法,其是D.S.C与D.S.C-Powell法的一部分。二次插值法的核心思想是在函数上取三个点,这三个点的函数值需要满足两头大,中间小,然后设一二次方程,将这三个点代入方程得到一个方程组,如下:
{ a x 1 2 + b x 1 + c = f ( x 1 ) a x 2 2 + b x 2 + c = f ( x 2 ) a x 3 2 + b x 3 + c = f ( x 3 ) \left\{ \begin{array}{c} ax_1^2 + bx_1 + c = f(x_1) \\ ax_2^2 + bx_2 + c = f(x_2) \\ ax_3^2 + bx_3 + c = f(x_3) \end{array} \right. ax12+bx1+c=f(x1)ax22+bx2+c=f(x2)ax32+bx3+c=f(x3)
化为矩阵的形式,也就是:
[ x 1 2 x 1 1 x 2 2 x 2 1 x 3 2 x 3 1 ] [ a b c ] = [ f ( x 1 ) f ( x 2 ) f ( x 3 ) ] \begin{aligned} \left[ \begin{matrix} x_1^2 & x_1 & 1\\ x_2^2 & x_2 & 1\\ x_3^2 & x_3 & 1\\ \end{matrix} \right] \left[ \begin{matrix} a\\ b\\ c\\ \end{matrix} \right] = \left[ \begin{matrix} f(x_1)\\ f(x_2)\\ f(x_3)\\ \end{matrix} \right] \end{aligned} x12x22x32x1x2x3111abc=f(x1)f(x2)f(x3)
我们把上式看作 A * X=f( X)的形式(有点奇怪),由于 A 是一个范德蒙行列式,所以 X 必有解。我们之后通过解这个线性方程组就可以得到二次函数的系数,从而确定二次函数的最低点( x ∗ = − b 2 a x^* = -\frac{b}{2a} x=2ab), x ∗ x^* x就是我们之前取得三点所在范围内可能得最低点,通过不断插值,我们会越来越接近真实值,下面给出了求解的一个大致过程:
在这里插入图片描述
如上图所示,黑线是原函数f(x),我们在该函数上取a,b,c三点,满足两头大,中间小的特点,然后通过这三个点拟合出一条二次函数曲线(蓝线),通过 x ∗ = − b 2 a x^* = -\frac{b}{2a} x=2ab,我们可以得到该二次函数的最低点,同时该点又对应原函数上一点d,然后我们将a,d,b作为下一次取点,不断重复这一过程求d点,最后我们会无限接近原函数的最小值点。现在的问题是有没有一个公式可以直接通过我们取得三个点得信息得出d点的坐标,下面给出推导过程和结论:
首先, 根据克罗姆法则我们可以直接求解得到,
a = ∣ f 1 x 1 1 f 2 x 2 1 f 3 x 3 1 ∣ / ∣ x 1 2 x 1 1 x 2 2 x 2 1 x 3 2 x 3 1 ∣ \begin{aligned} a = \left| \begin{matrix} f_1 & x_1 & 1\\ f_2 & x_2 & 1\\ f_3 & x_3 & 1\\ \end{matrix} \right| / \left| \begin{matrix} x_1^2 & x_1 & 1\\ x_2^2 & x_2 & 1\\ x_3^2 & x_3 & 1\\ \end{matrix} \right| \end{aligned} a=f1f2f3x1x2x3111/x12x22x32x1x2x3111
b = ∣ x 1 2 f 1 1 x 2 2 f 2 1 x 3 2 f 3 1 ∣ / ∣ x 1 2 x 1 1 x 2 2 x 2 1 x 3 2 x 3 1 ∣ \begin{aligned} b = \left| \begin{matrix} x_1^2 & f_1 & 1\\ x_2^2 & f_2 & 1\\ x_3^2 & f_3 & 1 \end{matrix} \right| / \left| \begin{matrix} x_1^2 & x_1 & 1\\ x_2^2 & x_2 & 1\\ x_3^2 & x_3 & 1 \end{matrix} \right| \end{aligned} b=x12x22x32f1f2f3111/x12x22x32x1x2x3111
x ∗ = − b 2 a = − 1 2 ∣ x 1 2 f 1 1 x 2 2 f 2 1 x 3 2 f 3 1 ∣ / ∣ f 1 x 1 1 f 2 x 2 1 f 3 x 3 1 ∣ \begin{aligned} x^* = -\frac{b}{2a} = -\frac{1}{2} \left| \begin{matrix} x_1^2 & f_1 & 1\\ x_2^2 & f_2 & 1\\ x_3^2 & f_3 & 1 \end{matrix} \right| / \left| \begin{matrix} f_1 & x_1 & 1\\ f_2 & x_2 & 1\\ f_3 & x_3 & 1\\ \end{matrix} \right| \end{aligned} x=2ab=21x12x22x32f1f2f3111/f1f2f3x1x2x3111
计算行列式可得
x ∗ = 1 2 ( x 2 2 − x 3 2 ) f 1 + ( x 3 2 − x 1 2 ) f 2 + ( x 1 2 − x 2 2 ) f 3 ( x 2 − x 3 ) f 1 + ( x 3 − x 1 ) f 2 + ( x 1 − x 2 ) f 3 (2-1) \begin{aligned} x^* = \frac{1}{2} \frac{(x_2^2-x_3^2)f_1+(x_3^2-x_1^2)f_2+(x_1^2-x_2^2)f_3}{(x_2-x_3)f_1+(x_3-x_1)f_2+(x_1-x_2)f_3} \end{aligned} \tag{2-1} x=21(x2x3)f1+(x3x1)f2+(x1x2)f3(x22x32)f1+(x32x12)f2+(x12x22)f3(2-1)
仔细观察这个式子,除了容易记忆之外几乎没有什么优点,计算量较大,抛开加减法不说,可以统计出乘除法进行了14次。我们的目的是计算 − b 2 a -\frac{b}{2a} 2ab,有没有其他的办法来计算这一比值呢,答案是肯定的。
用方程组第一行减去第二行可得:
a ( x 1 2 − x 3 2 ) + b ( x 1 − x 3 ) = f 1 − f 3 \begin{aligned} a(x_1^2-x_3^2)+b(x_1-x_3)=f_1-f_3 \end{aligned} a(x12x32)+b(x1x3)=f1f3
b = ( f 1 − f 3 ) − a ( x 1 2 − x 3 2 ) ( x 1 − x 3 ) = − a ( x 1 + x 3 ) + ( f 1 − f 3 ) ( x 1 − x 3 ) \begin{aligned} b = \frac{(f_1-f_3)-a(x_1^2-x_3^2)}{(x_1-x_3)} =-a(x_1+x_3)+\frac{(f_1-f_3)}{(x_1-x_3)} \end{aligned} b=(x1x3)(f1f3)a(x12x32)=a(x1+x3)+(x1x3)(f1f3)
c 1 = ( f 1 − f 3 ) ( x 1 − x 3 ) c_1 = \frac{(f_1-f_3)}{(x_1-x_3)} c1=(x1x3)(f1f3) b = − a ( x 1 + x 3 ) + c 1 b =-a(x_1+x_3)+c_1 b=a(x1+x3)+c1,则 b a = − ( x 1 + x 3 ) + c 1 a \frac{b}{a} = -(x_1+x_3)+ \frac{c_1}{a} ab=(x1+x3)+ac1
a = ∣ f 1 x 1 1 f 2 x 2 1 f 3 x 3 1 ∣ / ∣ x 1 2 x 1 1 x 2 2 x 2 1 x 3 2 x 3 1 ∣ = − ( x 2 − x 3 ) f 1 + ( x 3 − x 1 ) f 2 + ( x 1 − x 2 ) f 3 ( x 1 − x 2 ) ( x 2 − x 3 ) ( x 3 − x 1 ) = − ( x 2 − x 1 + x 1 − x 3 ) f 1 + ( x 3 − x 1 ) f 2 + ( x 1 − x 2 ) f 3 ( x 1 − x 2 ) ( x 2 − x 3 ) ( x 3 − x 1 ) = − ( x 1 − x 3 ) ( f 1 − f 2 ) + ( x 2 − x 1 ) ( f 1 − f 3 ) ( x 1 − x 2 ) ( x 2 − x 3 ) ( x 3 − x 1 ) = ( f 1 − f 2 ) ( x 1 − x 2 ) + ( f 1 − f 3 ) ( x 3 − x 1 ) ( x 2 − x 3 ) = ( f 1 − f 2 ) ( x 1 − x 2 ) − c 1 ( x 2 − x 3 ) \begin{aligned} a = \left| \begin{matrix} f_1 & x_1 & 1\\ f_2 & x_2 & 1\\ f_3 & x_3 & 1\\ \end{matrix} \right| / \left| \begin{matrix} x_1^2 & x_1 & 1\\ x_2^2 & x_2 & 1\\ x_3^2 & x_3 & 1\\ \end{matrix} \right| \end{aligned} = -\frac{(x_2-x_3)f_1+(x_3-x_1)f_2+(x_1-x_2)f_3}{(x_1-x_2)(x_2-x_3)(x_3-x_1)} \\ =-\frac{(x_2-x_1+x_1-x_3)f_1+(x_3-x_1)f_2+(x_1-x_2)f_3}{(x_1-x_2)(x_2-x_3)(x_3-x_1)} \\ =-\frac{(x_1-x_3)(f_1-f_2)+(x_2-x_1)(f_1-f_3)}{(x_1-x_2)(x_2-x_3)(x_3-x_1)} \\ =\frac{\frac{(f_1-f_2)}{(x_1-x_2)}+\frac{(f_1-f_3)}{(x_3-x_1)}}{(x_2-x_3)}\\ =\frac{\frac{(f_1-f_2)}{(x_1-x_2)}-c_1}{(x_2-x_3)}\\ a=f1f2f3x1x2x3111/x12x22x32x1x2x3111=(x1x2)(x2x3)(x3x1)(x2x3)f1+(x3x1)f2+(x1x2)f3=(x1x2)(x2x3)(x3x1)(x2x1+x1x3)f1+(x3x1)f2+(x1x2)f3=(x1x2)(x2x3)(x3x1)(x1x3)(f1f2)+(x2x1)(f1f3)=(x2x3)(x1x2)(f1f2)+(x3x1)(f1f3)=(x2x3)(x1x2)(f1f2)c1
c 2 = ( f 1 − f 2 ) ( x 1 − x 2 ) − c 1 ( x 2 − x 3 ) c_2 = \frac{\frac{(f_1-f_2)}{(x_1-x_2)}-c_1}{(x_2-x_3)} c2=(x2x3)(x1x2)(f1f2)c1,综上可得:
{ c 1 = ( f 1 − f 3 ) ( x 1 − x 3 ) c 2 = ( f 1 − f 2 ) ( x 1 − x 2 ) − c 1 ( x 2 − x 3 ) x ∗ = 1 2 [ ( x 1 + x 3 ) − c 1 c 2 ] (2-2) \left\{ \begin{array}{c} c_1 = \frac{(f_1-f_3)}{(x_1-x_3)}\\ c_2 = \frac{\frac{(f_1-f_2)}{(x_1-x_2)}-c_1}{(x_2-x_3)} \\ x^* =\frac{1}{2}[(x_1+x_3)-\frac{c_1}{c_2}] \end{array} \tag{2-2} \right. c1=(x1x3)(f1f3)c2=(x2x3)(x1x2)(f1f2)c1x=21[(x1+x3)c2c1](2-2)
可以很明显的看出,由(2-2)式求最小点位置只需做5次乘法,大大提高了计算效率。另外,若选择的三个点满足 x 2 − x 1 = d , x 3 − x 2 = d x_2-x_1=d,x_3-x_2=d x2x1=dx3x2=d条件时,式(2-1)与式(2-2)还可以进一步简化:
x ∗ = x 2 + ( f 1 − f 3 ) d f 1 − 2 f 2 + f 3 (2-3) \begin{aligned} x^* = x_2 + \frac{(f_1-f_3)d}{f_1-2f_2+f_3} \end{aligned} \tag{2-3} x=x2+f12f2+f3(f1f3)d(2-3)
{ c 1 = − ( f 1 − f 3 ) 2 d c 2 = f 1 − 2 f 2 + f 3 2 d 2 x ∗ = 1 2 [ ( x 1 + x 3 ) − c 1 c 2 ] (2-4) \left\{ \begin{array}{c} c_1 = -\frac{(f_1-f_3)}{2d}\\ c_2 = \frac{f_1-2f_2+f_3}{2d^2} \\ x^* =\frac{1}{2}[(x_1+x_3)-\frac{c_1}{c_2}] \end{array} \tag{2-4} \right. c1=2d(f1f3)c2=2d2f12f2+f3x=21[(x1+x3)c2c1](2-4)
在下面的D.S.C与D.S.C-Powell法中将会用到式(2-1)与(2-3)。

三、D.S.C法

D.S.C法是1964年Davies,Swann,Campey一起提出一种插值法,用于求解凸函数的最优解。这种方法是基于二次插值法设计的,同时借鉴了0.618分割法,其可以很快的找到凸函数的全局最优解。其过程如下:

  1. 给定初值 x 0 x_0 x0与搜索步长d
  2. 令k = 0,若 f ( x k + d ) < = f ( x k ) f(x_k + d) <= f(x_k) f(xk+d)<=f(xk),转第3步,否则d = 0 - d,转第3步
  3. x k + 1 = x k + d x_{k+1} = x_k + d xk+1=xk+d,计算 f ( x k + 1 ) f(x_{k+1}) f(xk+1)
  4. f ( x k + 1 ) < = f ( x k ) f(x_{k+1}) <= f(x_k) f(xk+1)<=f(xk),令d = 2 * d,k = k + 1,转第3步,否则令 d = d / 2 , x m = x k + 1 , x m + 1 = x m − d , x m − 1 = x k , x m − 2 = x k − 1 d = d / 2,x_m = x_{k+1},x_{m+1} = x_m-d,x_{m-1}=x_k,x_{m-2} = x_{k-1} d=d/2xm=xk+1xm+1=xmdxm1=xkxm2=xk1
  5. 在{ x m − 2 , x m − 1 , x m , x m + 1 x_{m-2},x_{m-1},x_{m},x_{m+1} xm2,xm1,xm,xm+1}中,若 f ( x m − 1 ) > f ( x m + 1 ) f(x_{m-1}) > f(x_{m+1}) f(xm1)>f(xm+1),则丢掉 x m x_m xm,令 x b = x m − 1 x_b = x_{m-1} xb=xm1,否则丢掉 x m − 2 x_{m-2} xm2,令 x b = x m + 1 x_b = x_{m+1} xb=xm+1
  6. x a = x b − d , x c = x b + d x_a = x_b - d,x_c = x_b + d xa=xbdxc=xb+d,做二次插值: x ∗ = x b + ( f ( x a ) − f ( x c ) ∗ d ) / ( 2 ∗ ( f ( x a ) − 2 ∗ f ( x b ) + f ( x c ) ) ) x^* = x_b + (f(x_a) - f(x_c)*d)/(2*(f(x_a) -2*f(x_b)+f(x_c))) x=xb+(f(xa)f(xc)d)/(2(f(xa)2f(xb)+f(xc)))
  7. ∣ x a − x b ∣ < ε |x_a - x_b| < \varepsilon xaxb<ε,停止迭代, x ∗ x^* x即为所求最优解,否则以 x ∗ x^* x为起点继续搜索, x 0 = x ∗ , d = d / 4 x_0 = x^*,d = d/4 x0=xd=d/4,转第2步

在这里插入图片描述
上述过程大致思路就是先找一个方向搜索直到函数值不再下降为止,取这次的点与前两次的点做二次插值得到一个新的最小点,将此点作为初始点重复上述过程,这样就可以逼近最小值点。

四、D.S.C-Powell法

这个方法与D.S.C法不同之处在于找到两头大中间小的点后的处理方式,D.S.C法将二次插值后的点设为初始点继续搜索,而D.S.C-Powell法通过重复二次插值逼近最小值点。

  1. 给定初值 x 0 x_0 x0与搜索步长d
  2. 令k = 0,若 f ( x k + d ) < = f ( x k ) f(x_k + d) <= f(x_k) f(xk+d)<=f(xk),转第3步,否则d = 0 - d,转第3步
  3. x k + 1 = x k + d x_{k+1} = x_k + d xk+1=xk+d,计算 f ( x k + 1 ) f(x_{k+1}) f(xk+1)
  4. f ( x k + 1 ) < = f ( x k ) f(x_{k+1}) <= f(x_k) f(xk+1)<=f(xk),令d = 2 * d,k = k + 1,转第3步,否则令 d = d / 2 , x m = x k + 1 , x m + 1 = x m − d , x m − 1 = x k , x m − 2 = x k − 1 d = d / 2,x_m = x_{k+1},x_{m+1} = x_m-d,x_{m-1}=x_k,x_{m-2} = x_{k-1} d=d/2xm=xk+1xm+1=xmdxm1=xkxm2=xk1
  5. 在{ x m − 2 , x m − 1 , x m , x m + 1 x_{m-2},x_{m-1},x_{m},x_{m+1} xm2,xm1,xm,xm+1}中,若 f ( x m − 1 ) > f ( x m + 1 ) f(x_{m-1}) > f(x_{m+1}) f(xm1)>f(xm+1),则丢掉 x m x_m xm,令 x 2 = x m − 1 x_2 = x_{m-1} x2=xm1,否则丢掉 x m − 2 x_{m-2} xm2,令 x 2 = x m + 1 , x 1 = x 2 − d , x 3 = x 2 + d x_2 = x_{m+1},x_1 = x_2 - d,x_3 = x_2 + d x2=xm+1x1=x2dx3=x2+d
  6. 做二次插值: x ∗ = 1 2 ( x 2 2 − x 3 2 ) f ( x 1 ) + ( x 3 2 − x 1 2 ) f ( x 2 ) + ( x 1 2 − x 2 2 ) f ( x 3 ) ( x 2 − x 3 ) f ( x 1 ) + ( x 3 − x 1 ) f ( x 2 ) + ( x 1 − x 2 ) f ( x 3 ) x^* = \frac{1}{2} \frac{(x_2^2-x_3^2)f(x_1)+(x_3^2-x_1^2)f(x_2)+(x_1^2-x_2^2)f(x_3)}{(x_2-x_3)f(x_1)+(x_3-x_1)f(x_2)+(x_1-x_2)f(x_3)} x=21(x2x3)f(x1)+(x3x1)f(x2)+(x1x2)f(x3)(x22x32)f(x1)+(x32x12)f(x2)+(x12x22)f(x3)
  7. ∣ x 1 − x 2 ∣ < ε |x_1 - x_2| < \varepsilon x1x2<ε,停止迭代, x ∗ x^* x即为所求最优解,否则以 x ∗ x^* x作为 x 2 x_2 x2,然后将从原来的三点中找到最靠近 x ∗ x^* x的两个点分别作为 x 1 x_1 x1 x 3 x_3 x3,转第6步

在这里插入图片描述
目前来讲,此法相对于D.S.C来讲要更好些,下面将给出程序设计源码与实验结果。

五、实验结果

测试用例:
f ( x ) = ( x + 4 ) 4 + 3 ( x + 4 ) 3 f(x) = (x+4)^4+3(x+4)^3 f(x)=(x+4)4+3(x+4)3
在这里插入图片描述
测试结果:
在这里插入图片描述

六、C++源码

#include <iostream>
#include <cmath>
#include <algorithm>
#include <ctime>using namespace std;//待求解函数
struct func{double operator()(double x) const{return  pow((x + 4), 4) + 3 * pow((x + 4), 3);}
};//D.S.C算法
class D_S_C{public:D_S_C(double start, double step):x0{start},delta{step}{iter = 0;}double run(func f, double precision);int get_iter() const {return iter;}double abs(double x){ return (x > 0)?x:(0 - x); }
private:double x0; //起点double delta; //步长double xk; //保存当前x的位置double xk1; //保存上一次x的位置double xk2; //保存上上一次x的位置int iter; //迭代次数};//D.S.C-Powell 算法
class D_S_C_Powell{
public:D_S_C_Powell(double start, double step):x0{start},delta{step}{iter = 0;}double run(func f, double precision);int get_iter() const {return iter;}double abs(double x){ return (x > 0)?x:(0 - x); }
private:double x0; //起点double delta; //步长double xk; //保存当前x的位置double xk1; //保存上一次x的位置double xk2; //保存上上一次x的位置int iter; //迭代次数
};int main(){D_S_C dsc(-10,0.0001);D_S_C_Powell dscp(-10,0.0001);auto t1 = clock();cout << "D.S.C Method result:" << endl;cout << "iteration : " << dsc.get_iter() << "\nMin point: "<< dsc.run(func(), 0.000001) << endl;auto t2 = clock();cout << "time : " << t2 - t1 << endl;t1 = clock();cout << "D.S.C-Powell Method result:" << endl;cout << "iteration : " << dscp.get_iter() << "\nMin point: "<< dscp.run(func(), 0.000001) << endl;t2 = clock();cout << "time : " << t2 - t1 << endl;return 0;}double D_S_C::run(func f, double precision){double fval = 0;double lfval = 0;xk = x0;do{if( f(xk + delta) > f(xk) ){ //判断该朝哪边寻找最低点delta = 0 - delta;}xk2 = xk;xk1 = xk;xk = xk + delta;lfval = f(xk1);fval = f(xk);while(fval <= lfval){ //找最低点delta = delta + delta; //步数加倍xk2 = xk1;xk1 = xk;xk = xk + delta;lfval = fval;fval = f(xk);}//退出循环时说明已近越过最低点delta = delta / 2;//从xk,xk-delta,xk1,xk2中选取三个点,其满足两头大,中间小if(f(xk - delta) > lfval){ //丢掉xkxk = xk - delta;}else{ //丢掉xk2xk2 = xk1;xk1 = xk - delta;}//做二次插值xk = xk1 + (f(xk2) - f(xk)) * delta / (2 * (f(xk2) - 2 * f(xk1) + f(xk)));delta = delta / 4; //缩短步距iter++;}while(abs(xk - xk2) >= precision); // 符合精度停止迭代return xk;}double D_S_C_Powell::run(func f, double precision){double fval = 0;double lfval = 0;xk = x0;if( f(xk + delta) > f(xk) ){ //判断该朝哪边寻找最低点delta = 0 - delta;}xk2 = xk;xk1 = xk;xk = xk + delta;lfval = f(xk1);fval = f(xk);while(fval <= lfval){ //找最低点delta = delta + delta; //步数加倍xk2 = xk1;xk1 = xk;xk = xk + delta;lfval = fval;fval = f(xk);}//退出循环时说明已近越过最低点delta = delta / 2;//从xk,xk-delta,xk1,xk2中选取三个点,其满足两头大,中间小if(f(xk - delta) > lfval){ //丢掉xkxk = xk - delta;}else{ //丢掉xk2xk2 = xk1;xk1 = xk - delta;}do{//做二次插值double fxk = f(xk);double fxk1 = f(xk1);double fxk2 = f(xk2);double a = (xk1*xk1-xk2*xk2)*fxk + (xk2*xk2-xk*xk)*fxk1 + (xk*xk-xk1*xk1)*fxk2;double b = (xk1-xk2)*fxk + (xk2-xk)*fxk1 + (xk-xk1)*fxk2;double xmin = 0.5 * a / b;if(xmin < xk1){ //丢掉xkxk = xk1;xk1 = xmin;}else{ //丢掉xk2xk2 = xk1;xk1 = xmin;}iter++;}while(abs(xk - xk2) >= precision && abs(xk - xk1) >= precision); // 符合精度停止迭代return xk;}

这篇关于优化算法之D.S.C法与D.S.C-Powell法及其C++代码实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/500150

相关文章

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

Windows下C++使用SQLitede的操作过程

《Windows下C++使用SQLitede的操作过程》本文介绍了Windows下C++使用SQLite的安装配置、CppSQLite库封装优势、核心功能(如数据库连接、事务管理)、跨平台支持及性能优... 目录Windows下C++使用SQLite1、安装2、代码示例CppSQLite:C++轻松操作SQ

PostgreSQL中MVCC 机制的实现

《PostgreSQL中MVCC机制的实现》本文主要介绍了PostgreSQL中MVCC机制的实现,通过多版本数据存储、快照隔离和事务ID管理实现高并发读写,具有一定的参考价值,感兴趣的可以了解一下... 目录一 MVCC 基本原理python1.1 MVCC 核心概念1.2 与传统锁机制对比二 Postg

SpringBoot整合Flowable实现工作流的详细流程

《SpringBoot整合Flowable实现工作流的详细流程》Flowable是一个使用Java编写的轻量级业务流程引擎,Flowable流程引擎可用于部署BPMN2.0流程定义,创建这些流程定义的... 目录1、流程引擎介绍2、创建项目3、画流程图4、开发接口4.1 Java 类梳理4.2 查看流程图4

C++中RAII资源获取即初始化

《C++中RAII资源获取即初始化》RAII通过构造/析构自动管理资源生命周期,确保安全释放,本文就来介绍一下C++中的RAII技术及其应用,具有一定的参考价值,感兴趣的可以了解一下... 目录一、核心原理与机制二、标准库中的RAII实现三、自定义RAII类设计原则四、常见应用场景1. 内存管理2. 文件操

C++中零拷贝的多种实现方式

《C++中零拷贝的多种实现方式》本文主要介绍了C++中零拷贝的实现示例,旨在在减少数据在内存中的不必要复制,从而提高程序性能、降低内存使用并减少CPU消耗,零拷贝技术通过多种方式实现,下面就来了解一下... 目录一、C++中零拷贝技术的核心概念二、std::string_view 简介三、std::stri

C++高效内存池实现减少动态分配开销的解决方案

《C++高效内存池实现减少动态分配开销的解决方案》C++动态内存分配存在系统调用开销、碎片化和锁竞争等性能问题,内存池通过预分配、分块管理和缓存复用解决这些问题,下面就来了解一下... 目录一、C++内存分配的性能挑战二、内存池技术的核心原理三、主流内存池实现:TCMalloc与Jemalloc1. TCM

OpenCV实现实时颜色检测的示例

《OpenCV实现实时颜色检测的示例》本文主要介绍了OpenCV实现实时颜色检测的示例,通过HSV色彩空间转换和色调范围判断实现红黄绿蓝颜色检测,包含视频捕捉、区域标记、颜色分析等功能,具有一定的参考... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间

Python实例题之pygame开发打飞机游戏实例代码

《Python实例题之pygame开发打飞机游戏实例代码》对于python的学习者,能够写出一个飞机大战的程序代码,是不是感觉到非常的开心,:本文主要介绍Python实例题之pygame开发打飞机... 目录题目pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本代码解释初始化部

Python实现精准提取 PDF中的文本,表格与图片

《Python实现精准提取PDF中的文本,表格与图片》在实际的系统开发中,处理PDF文件不仅限于读取整页文本,还有提取文档中的表格数据,图片或特定区域的内容,下面我们来看看如何使用Python实... 目录安装 python 库提取 PDF 文本内容:获取整页文本与指定区域内容获取页面上的所有文本内容获取