优化算法之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如何实现读取csv文件时忽略文件的编码格式

《Python如何实现读取csv文件时忽略文件的编码格式》我们再日常读取csv文件的时候经常会发现csv文件的格式有多种,所以这篇文章为大家介绍了Python如何实现读取csv文件时忽略文件的编码格式... 目录1、背景介绍2、库的安装3、核心代码4、完整代码1、背景介绍我们再日常读取csv文件的时候经常

Golang中map缩容的实现

《Golang中map缩容的实现》本文主要介绍了Go语言中map的扩缩容机制,包括grow和hashGrow方法的处理,具有一定的参考价值,感兴趣的可以了解一下... 目录基本分析带来的隐患为什么不支持缩容基本分析在 Go 底层源码 src/runtime/map.go 中,扩缩容的处理方法是 grow

Go 1.23中Timer无buffer的实现方式详解

《Go1.23中Timer无buffer的实现方式详解》在Go1.23中,Timer的实现通常是通过time包提供的time.Timer类型来实现的,本文主要介绍了Go1.23中Timer无buff... 目录Timer 的基本实现无缓冲区的实现自定义无缓冲 Timer 实现更复杂的 Timer 实现总结在

基于Python实现多语言朗读与单词选择测验

《基于Python实现多语言朗读与单词选择测验》在数字化教育日益普及的今天,开发一款能够支持多语言朗读和单词选择测验的程序,对于语言学习者来说无疑是一个巨大的福音,下面我们就来用Python实现一个这... 目录一、项目概述二、环境准备三、实现朗读功能四、实现单词选择测验五、创建图形用户界面六、运行程序七、

Vue中动态权限到按钮的完整实现方案详解

《Vue中动态权限到按钮的完整实现方案详解》这篇文章主要为大家详细介绍了Vue如何在现有方案的基础上加入对路由的增、删、改、查权限控制,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、数据库设计扩展1.1 修改路由表(routes)1.2 修改角色与路由权限表(role_routes)二、后端接口设计

C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)

《C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)》本文主要介绍了C#集成DeepSeek模型实现AI私有化的方法,包括搭建基础环境,如安装Ollama和下载DeepS... 目录前言搭建基础环境1、安装 Ollama2、下载 DeepSeek R1 模型客户端 ChatBo

Qt实现发送HTTP请求的示例详解

《Qt实现发送HTTP请求的示例详解》这篇文章主要为大家详细介绍了如何通过Qt实现发送HTTP请求,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、添加network模块2、包含改头文件3、创建网络访问管理器4、创建接口5、创建网络请求对象6、创建一个回复对

C++实现回文串判断的两种高效方法

《C++实现回文串判断的两种高效方法》文章介绍了两种判断回文串的方法:解法一通过创建新字符串来处理,解法二在原字符串上直接筛选判断,两种方法都使用了双指针法,文中通过代码示例讲解的非常详细,需要的朋友... 目录一、问题描述示例二、解法一:将字母数字连接到新的 string思路代码实现代码解释复杂度分析三、

grom设置全局日志实现执行并打印sql语句

《grom设置全局日志实现执行并打印sql语句》本文主要介绍了grom设置全局日志实现执行并打印sql语句,包括设置日志级别、实现自定义Logger接口以及如何使用GORM的默认logger,通过这些... 目录gorm中的自定义日志gorm中日志的其他操作日志级别Debug自定义 Loggergorm中的

Spring Boot整合消息队列RabbitMQ的实现示例

《SpringBoot整合消息队列RabbitMQ的实现示例》本文主要介绍了SpringBoot整合消息队列RabbitMQ的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录RabbitMQ 简介与安装1. RabbitMQ 简介2. RabbitMQ 安装Spring