进化算法(遗传算法、粒子群算法、差分算法)—— Rosenbrock函数优化_差分进化算法和粒子群-程序员宅基地

技术标签: 算法  学习日志  机器学习  

进化算法

进化算法是一类算法簇,这类算法模拟的是自然界当中生物种群的进化机制。进化算法在解决最优化问题或者机器学习问题的时候,通常会维护一个解的集合 X = { x 1 , x 2 , … , x N } X=\{x_1,x_2,\dots,x_N\} X={ x1,x2,,xN},称之为种群, N N N称为种群规模。算法运行的机制,是在每一轮迭代当中,对种群进行变异、交叉等操作,形成新的个体添加到种群当中,然后对种群进行筛选,使得种群的规模始终维持在 N N N. 筛选的规则是根据种群个体的适应度 f ( x i ) f(x_i) f(xi)设计的,理想的筛选规则应当保留适应度高的个体,淘汰适应度低的个体。

1. 三种算法的标准式表述

我们这里介绍的进化算法,主要是三种:遗传算法、粒子群算法和标准差分算法。

首先我们先定义基本的问题背景:在一个环境 env \text{env} env(可能是一个最优化问题、一个强化学习场景、一个实际的工程模拟)当中,每一个解都表示为向量 x i ∈ R d x_i\in\R^d xiRd. 存在一个适应度函数 f ( x i ) f(x_i) f(xi)能够评价每一个解的适应性,函数评分越高,说明解越适应于该环境。

我们接下来分别介绍三种算法解决该问题的流程。

1.1 遗传算法

遗传算法模拟的是自然界中生物种群的繁衍以及自然选择机制。一个遗传算法的流程可以表示为:

  1. 初始化种群 X X X,设置进化代序为 t = 0 t=0 t=0
  2. 计算种群的适应度,并且利用选择算子筛选进行遗传的个体 X c = select ( X ) X_c=\text{select}(X) Xc=select(X)
  3. 对进行遗传的个体进行交叉算子操作 X m = crossover ( X c ) X_m=\text{crossover}(X_c) Xm=crossover(Xc)
  4. 对全体种群进行变异操作 X ′ = mutation ( X m ) X'=\text{mutation}(X_m) X=mutation(Xm)
  5. 更新种群 X = Reproduction ( X ′ ) X=\text{Reproduction}(X') X=Reproduction(X)
  6. 检查是否满足终止条件,若不满足,更新进化代序 t = t + 1 t=t+1 t=t+1并返回第2步

需要注意的是,遗传算法同样是一个算法簇,而不是某一具体算法。对于具体的实现,筛选、交叉、变异算子在算法流程中的顺序,以及它们对当前种群的更新机制会有一定的差异。

在这个流程当中,最为关键的是三个遗传算子: select ( ⋅ ) , crossover ( ⋅ ) , mutation ( ⋅ ) \text{select}(\cdot),\text{crossover}(\cdot),\text{mutation}(\cdot) select(),crossover(),mutation(),还有一个非关键的更新算子 Reproduction \text{Reproduction} Reproduction.

1.1.1 比例选择算子

假设每一个个体的适应度 f ( x i ) f(x_i) f(xi)都是非负的,那么进行变换

p i = f ( x i ) ∑ j = 1 N f ( x j ) p_i=\frac{f(x_i)}{\sum_{j=1}^Nf(x_j)} pi=j=1Nf(xj)f(xi)

在选择过程中,每个个体被选中加入交叉种群 X c X_c Xc的概率是 p i p_i pi. 实现这种选择的方法,可以采用轮盘抽奖的算法。假设我们在面积为 1 1 1的抽奖圆盘上,为每一个个体分配面积为 p i p_i pi的扇面,然后转动圆盘,当圆盘停止时,指针指向第 i i i个个体的扇面的概率恰好是 p i p_i pi. 如图:

在这里插入图片描述

从计算机程序实现角度来说,我们可以规定一个起始坐标 q 0 = 0 q_0=0 q0=0,然后用累加概率的方式找出剩下的各个分界点坐标

q i = ∑ j = 1 i p i q_i=\sum_{j=1}^ip_i qi=j=1ipi

随机取一个 [ q 0 , q N ] [q_0,q_N] [q0,qN]之间的点 λ \lambda λ,如果 λ ∈ [ q i − 1 , q i ] \lambda\in[q_{i-1},q_i] λ[qi1,qi],那就意味着指针落在了 x i x_i xi对应的圆盘扇面内, x i x_i xi被选中加入 X c X_c Xc。把这个过程重复 N N N次,就会选择出期望为 N p c Np_c Npc个的种群个体。

这种采样过程产生的交叉种群数 N c N_c Nc是不固定的,而且比原始种群数 N N N要少,需要一定的机制,例如将交叉运算后的个体添加回原种群当中,才能保证种群的数目不会随着迭代次数增加而减少。

1.1.2 其他选择算子

最优选择算子:这种算子通常指定一个数量 c < N c<N c<N,在每一轮迭代当中,它用当前种群里适应度最高的 c c c个个体,替换掉适应度最低的 c c c个个体,然后直接用得到的新种群作为 X c X_c Xc。更新后的种群继续进行交叉、变异算子的操作。

最优保存算子:这种算子不对种群进行筛选, X c = X X_c=X Xc=X. 只是记录下当前适应度最高的个体。最后在进行交叉、变异结束之后的种群 X ′ X' X中,将最优个体插入其中。使得最优个体保持到下一轮迭代。

生存数目算子:计算每一个个体适应度与平均适应度的比值,并且下取整:

N i = ⌊ N f ( x i ) ∑ j = 1 N f ( x j ) ⌋ N_i=\lfloor\frac{Nf(x_i)}{\sum_{j=1}^Nf(x_j)}\rfloor Ni=j=1Nf(xj)Nf(xi)

将原种群当中的每一个个体 x i x_i xi,复制 N i N_i Ni次,加入到交叉种群 X c X_c Xc当中。按照适应度对于 X c X_c Xc排序,截取其前 N N N个个体。

1.1.3 交叉算子

一般来说,交叉算子总是规定了交叉概率 P c P_c Pc,并且希望交叉运算产生的子代数目期望为 N c P c N_cP_c NcPc. 交叉算子有一个重要的问题是,交叉的两个父本如何选择。这个问题没有固定解法。有的算法当中,会将交叉种群 X c X_c Xc打乱顺序,之后按顺序两两匹配,对于每一个匹配都以 P c P_c Pc的概率进行交叉或不交叉;有的算法会随机抽取 n n n轮,每轮抽取一对父本以 P c P_c Pc的概率进行交叉或不交叉;有的算法会随机产生一个 ( 0 , 1 ) (0,1) (0,1)之间的随机数 λ \lambda λ,如果 λ < P c \lambda<P_c λ<Pc,就对整个 N c N_c Nc进行打乱、按顺序两两匹配、交叉运算,否则就完全不进行交叉运算。

交叉算子最常用的是单点交叉算子,即随机地在个体向量上取一个点位 min \text{min} min. 对于配对的两个向量 x i , x j x_i,x_j xi,xj,将它们从点位 min \text{min} min开始直到结束的片段交换:

x ‾ i , n = x j , n ,   n ≥ min x ‾ j , n = x i , n ,   n ≥ min \overline x_{i,n}=x_{j,n},\ n\geq\text{min}\\ \overline x_{j,n}=x_{i,n},\ n\geq\text{min} xi,n=xj,n, nminxj,n=xi,n, nmin

其次还有双点位交叉,即选择两个点位 min , max \text{min},\text{max} min,max,交换父本在这两个点位之间的片段。

有的时候,还会使用凸组合交叉算子,即随机采样一个 a ∈ ( 0 , 1 ) a\in(0,1) a(0,1),令

x ‾ i = a x i + ( 1 − a ) x j x ‾ j = ( 1 − a ) x i + a x j \overline x_i=ax_i+(1-a)x_j\\ \overline x_j=(1-a)x_i+ax_j xi=axi+(1a)xjxj=(1a)xi+axj

这种算子适用于解空间是高维凸域的情形。

最后一个问题是,交叉算子产生的子代和父代如何进行取舍。有的算法是将子代添加到种群 X c X_c Xc中组合形成 X ′ X' X,然后通过更新算子 Reproduction ( X ′ ) \text{Reproduction}(X') Reproduction(X)进行取舍(例如选择出适应度前 N N N个个体)。有的算法会比较子代与父代的适应度,然后选择保留适应度强的子代。

1.1.4 变异算子

变异算子同样指定一个变异概率 P m P_m Pm,并且试图使变异的个体数期望为 N m P m N_mP_m NmPm. 而实现的方法,可以是对于 X m X_m Xm的每一个个体都进行二分决策,以 P m P_m Pm的概率进行突变,也可以是对整个 X m X_m Xm进行二分决策,突变或者不突变。

对于每一个突变的个体,如果是二进制串(二进制的向量),可以直接进行位反转。

对于一般的向量,还可以随机选取一个片段进行倒置(顺序颠倒),或者选择两个点位互换数值。

和交叉算子类似,变异算子也可以采用线性组合的方式进行变异:随机选取一个 v ∈ R d v\in\R^d vRd和一个 λ ∈ ( 0 , 1 ) \lambda\in(0,1) λ(0,1),令

x ^ i = x i + λ v \hat x_i=x_i+\lambda v x^i=xi+λv

1.1.5 更新算子

更新算子的实现很简单,如果选择、交叉、变异算子最终产生的种群 X ′ X' X规模是 N N N,可以直接将其更新到 X X X上. 如果数目超过 N N N,那么可以选择保留适应度最高的 N N N个个体。(也就是需要再次遍历并且进行适应度评价)

1.2 粒子群算法

粒子群算法和遗传算法的区别在于,粒子群算法没有交叉、变异的相关概念,而是会在每一轮迭代当中,更新每一个个体的值。在粒子群算法当中,种群当中的个体称为粒子,由两个 d d d维的向量 x i ∈ R d , v i ∈ R d x_i\in\R^d,v_i\in\R^d xiRd,viRd表示, x i x_i xi称为粒子的位置, v i v_i vi称为粒子的速度。一个种群可以表示为 E = ( X , V ) E=(X,V) E=(X,V),其中 X = ( x 1 , x 2 , … , x N ) X=(x_1,x_2,\dots,x_N) X=(x1,x2,,xN) V = ( v 1 , v 2 , … , v N ) V=(v_1,v_2,\dots,v_N) V=(v1,v2,,vN). 环境中的适应性函数仅仅取决于位置 f ( x i ) f(x_i) f(xi).

粒子群算法当中,每一个粒子都需要维护两个变量 p i ∈ R , P i ∈ R d p_i\in\R, P_i\in\R^d piR,PiRd,其中 p i p_i pi是在以往迭代轮数当中,粒子 i i i所取得的最大适应度,而 P i P_i Pi是取得该适应度时的位置。

同时在每一轮迭代当中,还要找出两个变量 s ∈ R , S ∈ R d s\in\R,S\in\R^d sR,SRd,分别是当前种群当中,适应度的最大值,以及适应度最大的粒子所处位置。

标准粒子群算法的参数包括:

  1. 最大进化代数 G G G
  2. 学习因子 c 1 , c 2 c_1,c_2 c1,c2
  3. 粒子群规模 N N N
  4. 可行集: D ⊂ R d D\sub \R^d DRd

标准粒子群算法的流程可以描述为:

1 初始化

随机生成(或按照一定分布)粒子群 X ( t = 1 ) , V ( t = 1 ) X^{(t=1)},V^{(t=1)} X(t=1),V(t=1),根据初始化条件计算 p i ( 0 ) , P i ( 0 ) p_i^{(0)},P_i^{(0)} pi(0),Pi(0),迭代轮数置为 t = 1 t=1 t=1

2 计算适应度

计算每一个粒子的适应度 f ( x i ) f(x_i) f(xi),若 f ( x i ) > p i ( t − 1 ) f(x_i)>p_i^{(t-1)} f(xi)>pi(t1),则更新 p i ( t ) = f ( x i ) , P i ( t ) = x i p_i^{(t)}=f(x_i),P_i^{(t)}=x_i pi(t)=f(xi),Pi(t)=xi,否则 p i ( t ) = p i ( t − 1 ) , P i ( t ) = P i ( t − 1 ) p_i^{(t)}=p_i^{(t-1)}, P_i^{(t)}=P_i^{(t-1)} pi(t)=pi(t1),Pi(t)=Pi(t1)

计算出当前种群最优: s ( t ) , S ( t ) s^{(t)}, S^{(t)} s(t),S(t)

3 更新粒子

按照如下公式更新粒子的速度和位置:

v i ( t + 1 ) = ω ( t ) v i ( t ) + c 1 r 1 ( P i ( t ) − x i ( t ) ) + c 2 r 2 ( S ( t ) − x i ( t ) ) x i ( t + 1 ) = x i ( t ) + v i ( t ) \begin{align*} &v_i^{(t+1)}=\omega(t)v_i^{(t)}+c_1r_1(P_i^{(t)}-x_i^{(t)})+c_2r_2(S^{(t)}-x_i^{(t)})\\ &x_i^{(t+1)}=x_i^{(t)}+v_i^{(t)} \end{align*} vi(t+1)=ω(t)vi(t)+c1r1(Pi(t)xi(t))+c2r2(S(t)xi(t))xi(t+1)=xi(t)+vi(t)

其中 ω ( t ) \omega(t) ω(t)是随迭代轮数自适应的惯性因子,而 r 1 r_1 r1 r 2 r_2 r2是两个 ( 0 , 1 ) (0,1) (0,1)间的随机数.

4 检查结束条件

如果满足结束条件或 t > G t>G t>G,则算法终止,否则返回到2,并且设置 t = t + 1 t=t+1 t=t+1.

粒子群算法当中的位置和速度更新公式

v i ( t + 1 ) = ω ( t ) v i ( t ) + c 1 r 1 ( P i ( t ) − x i ( t ) ) + c 2 r 2 ( S ( t ) − x i ( t ) ) x i ( t + 1 ) = x i ( t ) + v i ( t ) \begin{align*} &v_i^{(t+1)}=\omega(t)v_i^{(t)}+c_1r_1(P_i^{(t)}-x_i^{(t)})+c_2r_2(S^{(t)}-x_i^{(t)})\\ &x_i^{(t+1)}=x_i^{(t)}+v_i^{(t)} \end{align*} vi(t+1)=ω(t)vi(t)+c1r1(Pi(t)xi(t))+c2r2(S(t)xi(t))xi(t+1)=xi(t)+vi(t)

模拟的是单个智能体的决策过程。每个智能体都有回到其历史最优值的趋势 P i ( t ) − x i ( t ) P_i^{(t)}-x_i^{(t)} Pi(t)xi(t),前往种群最优值的趋势 S ( t ) − x i ( t ) S^{(t)}-x_i^{(t)} S(t)xi(t),智能体通过一个随机权值组合 ( c 1 r 1 , c 2 r 2 ) (c_1r_1,c_2r_2) (c1r1,c2r2)来将这两个趋势结合起来。同时,智能体由于先前的速度,在物理空间中存在惯性 ω ( t ) v i ( t ) \omega(t)v_i^{(t)} ω(t)vi(t). 这三个部分组合在一起,就构成了对速度的改变量。而位置的改变,就是速度,这是符合物理直觉的。

1.2.1 局部粒子群算法

为了增加更多的随机性,避免算法陷入局部最优值,我们还可以对标准粒子群算法进行修改,得到局部粒子群算法。局部粒子群算法相比较于标准粒子群算法的改动在于:当前迭代轮次当中,每个粒子都计算一个局部适应度最优值 s i ( t ) s_i^{(t)} si(t)和局部最优位置 S i ( t ) S_i^{(t)} Si(t). 局部 s i ( t ) s_i^{(t)} si(t) S i ( t ) S_i^{(t)} Si(t)的选择范围,通常是编号与 i i i相近的个体。例如我们可以取

s i ( t ) = Best ( f ( x i − 1 ( t ) ) , f ( x i ( t ) ) , f ( x i + 1 ( t ) ) ) S i ( t ) = BestX ( f ( x i − 1 ( t ) ) , f ( x i ( t ) ) , f ( x i + 1 ( t ) ) ) s_i^{(t)}=\text{Best}(f(x_{i-1}^{(t)}),f(x_i^{(t)}),f(x_{i+1}^{(t)}))\\ S_i^{(t)}=\text{BestX}(f(x_{i-1}^{(t)}),f(x_i^{(t)}),f(x_{i+1}^{(t)})) si(t)=Best(f(xi1(t)),f(xi(t)),f(xi+1(t)))Si(t)=BestX(f(xi1(t)),f(xi(t)),f(xi+1(t)))

相应的,粒子的更新算法也要修改为

v i ( t + 1 ) = ω ( t ) v i ( t ) + c 1 r 1 ( P i ( t ) − x i ( t ) ) + c 2 r 2 ( S i ( t ) − x i ( t ) ) x i ( t + 1 ) = x i ( t ) + v i ( t ) \begin{align*} &v_i^{(t+1)}=\omega(t)v_i^{(t)}+c_1r_1(P_i^{(t)}-x_i^{(t)})+c_2r_2(S_i^{(t)}-x_i^{(t)})\\ &x_i^{(t+1)}=x_i^{(t)}+v_i^{(t)} \end{align*} vi(t+1)=ω(t)vi(t)+c1r1(Pi(t)xi(t))+c2r2(Si(t)xi(t))xi(t+1)=xi(t)+vi(t)

1.3 差分算法

差分算法类似于遗传算法,具有选择、交叉、变异三个流程。

标准的差分算法可以表述为:

1 初始化

随机初始化一个由 N N N d d d维行向量组成的集合: X ( 0 ) = { x i ( 0 ) ∈ R d ∣ i = 1 , 2 , … , N } X^{(0)}=\{x_i^{(0)}\in\R^d|i=1,2,\dots,N\} X(0)={ xi(0)Rdi=1,2,,N},称为种群

初始化变异矩阵 H ( 0 ) = 0 ∈ R N × d H^{(0)}=\bm 0\in \R^{N\times d} H(0)=0RN×d

初始化子代矩阵 V ( 0 ) = 0 ∈ R N × d V^{(0)}=\bm 0\in \R^{N\times d} V(0)=0RN×d

初始化进化代数 t = 0 t=0 t=0

2 差分变异

对于每一个个体 x i ( t ) x_{i}^{(t)} xi(t),随机选择三个各不相同的个体 x p 1 ( t ) , x p 2 ( t ) , x p 3 ( t ) ,   ( i ≠ p 1 ≠ p 2 ≠ p 3 ) x_{p_1}^{(t)},x_{p_2}^{(t)},x_{p_3}^{(t)},\ (i\neq p_1\neq p_2\neq p_3) xp1(t),xp2(t),xp3(t), (i=p1=p2=p3). 计算出变异向量:

h i ( t + 1 ) = x p 1 ( t ) + F ( x p 2 ( t ) − x p 3 ( t ) ) h_i^{(t+1)}=x_{p_1}^{(t)}+F(x_{p_2}^{(t)}-x_{p_3}^{(t)}) hi(t+1)=xp1(t)+F(xp2(t)xp3(t))

如果不存在局部最优问题,也就是环境当中的局部最优适应度等价于整体最优适应度,那么可以把 x p 1 ( t ) x_{p_1}^{(t)} xp1(t)替换为当前种群中适应度最高的个体 x b t x_b^{t} xbt,即

h i ( t + 1 ) = x b ( t ) + F ( x p 2 ( t ) − x p 3 ( t ) ) h_i^{(t+1)}=x_{b}^{(t)}+F(x_{p_2}^{(t)}-x_{p_3}^{(t)}) hi(t+1)=xb(t)+F(xp2(t)xp3(t))

这样会使得收敛更快

3 交叉操作

对于每一个个体 i , j i,j i,j,随机采样一个 λ ∈ ( 0 , 1 ) \lambda\in(0,1) λ(0,1),计算子代单点位值:

v i j ( t + 1 ) = { h i j ( t + 1 ) , λ < c x i j ( t ) , λ ≥ c v_{ij}^{(t+1)}=\begin{cases} h_{ij}^{(t+1)},&\lambda<c\\ x_{ij}{(t)},&\lambda\geq c \end{cases} vij(t+1)={ hij(t+1),xij(t),λ<cλc

4 选择操作

对于每一个个体编号 i i i,判断子代向量 v i ( t + 1 ) v_i^{(t+1)} vi(t+1)和父代 x i ( t ) x_i^{(t)} xi(t)的适应度,保留适应度更大的一个:

x i ( t + 1 ) = { x i ( t ) , f ( x i ( t ) ) ≥ f ( v i ( t + 1 ) ) v i ( t + 1 ) , f ( x i ( t ) ) < f ( v i ( t + 1 ) ) x_i^{(t+1)}=\begin{cases} x_i^{(t)},&f(x_i^{(t)})\geq f(v_i^{(t+1)})\\ v_i^{(t+1)},&f(x_i^{(t)})<f(v_i^{(t+1)}) \end{cases} xi(t+1)={ xi(t),vi(t+1),f(xi(t))f(vi(t+1))f(xi(t))<f(vi(t+1))

2. 案例:Rosenbrock函数的最优化

Rosenbrock函数的定义式为:

{ f ( x 1 , x 2 ) = 100 ( x 1 2 − x 2 2 ) + ( 1 − x 1 ) 2 − 2.048 ≤ x i ≤ 2.048 , i = 1 , 2 \begin{cases} f(x_1,x_2)=100(x_1^2-x_2^2)+(1-x_1)^2\\ -2.048\leq x_i\leq 2.048,&i=1,2 \end{cases} { f(x1,x2)=100(x12x22)+(1x1)22.048xi2.048,i=1,2

我们想要求解如下最优化问题

max x 1 , x 2   f ( x 1 , x 2 ) s.t.  − 2.048 ≤ x i ≤ 2.048 , i = 1 , 2 \begin{align*} \mathop\text{max}\limits_{x_1,x_2}\ &f(x_1,x_2)\\ \text{s.t.}\ &-2.048\leq x_i\leq 2.048,&i=1,2 \end{align*} x1,x2max s.t. f(x1,x2)2.048xi2.048,i=1,2

2.1 解的编码

Rosenbrock最优化的可行解空间是 [ − 2.048 , 2.048 ] 2 ⊂ R 2 [-2.048,2.048]^2\sub\R^2 [2.048,2.048]2R2,我们可以把这个空间离散化,在 x 1 , x 2 x_1,x_2 x1,x2轴上,分别以长度 0.004 0.004 0.004为单位,划分成离散的区间片段。以区间 [ − 2.048 , − 2.044 ) [-2.048,-2.044) [2.048,2.044)编号为 0 0 0,沿着实数轴的正向递增地编号为 0 , 1 , … , 1023 0,1,\dots,1023 0,1,,1023.

在两个轴上分别取一个区间,编号组合为 ( i , j ) (i,j) (i,j),它们的交叉部分就是一个可行解空间上的矩形区域。把 i , j i,j i,j都转换成10位的二进制串,再首位拼接为20位的二进制串 x x x,就把这个二进制串视为区间 [ 0.004 i − 2.048 , 0.004 i − 2.044 ] × [ 0.004 j − 2.048 , 0.004 j − 2.044 ] [0.004i-2.048,0.004i-2.044]\times[0.004j-2.048,0.004j-2.044] [0.004i2.048,0.004i2.044]×[0.004j2.048,0.004j2.044]内任何一个点的编码,而反过来,用点 ( 0.004 i − 2.048 , 0.004 j − 2.048 ) (0.004i-2.048,0.004j-2.048) (0.004i2.048,0.004j2.048)作为 x x x的解码值。

把编码和解码的流程写作算子 encode ( ⋅ ) \text{encode}(\cdot) encode() decode ( ⋅ ) \text{decode}(\cdot) decode()

2.2 应用遗传算法

参数:

  1. 种群规模: N = 80 N=80 N=80
  2. 迭代次数: G = 100 G=100 G=100
  3. 交叉概率: p c = 0.6 p_c=0.6 pc=0.6
  4. 变异概率: p m = 0.1 p_m=0.1 pm=0.1

流程:

  1. 随机生成 N N N个20位的二进制串 E = { x 1 , … , x N } E=\{x_1,\dots,x_N\} E={ x1,,xN}
  2. 对每一个 x i ∈ E x_i\in E xiE,解码为浮点数 ( u i , v i ) = decode ( x i ) (u_i,v_i)=\text{decode}(x_i) (ui,vi)=decode(xi)
  3. 计算每一个解码值的Rosenbrock值 f i = f ( u i , v i ) f_i=f(u_i,v_i) fi=f(ui,vi),并作为对应个体的适应度
  4. 按适应度对 E E E进行排序,记录下 x b = x N x_b=x_N xb=xN,删除排在 x N x_N xN以后的个体(如果有的话)
  5. 选择交叉种群 E c = Select ( E ) E_c=\text{Select}(E) Ec=Select(E)
  6. 进行交叉计算 E = Crossover ( E c ) E=\text{Crossover}(E_c) E=Crossover(Ec)
  7. E E E当中的第 N N N个个体置为 x m x_m xm(这是利用了最优保存策略)
  8. 进行变异计算 E = Mutation ( E m ) E=\text{Mutation}(E_m) E=Mutation(Em)
  9. E E E当中的第 N N N个个体置为 x m x_m xm
  10. 判断是否达到最大迭代次数 G G G,若达到则终止迭代,否则返回第2步
  11. 取终止迭代时,群体中的最优个体为算法的结果
2.2.1 选择算子

E c = Select ( E ) E_c=\text{Select}(E) Ec=Select(E)是这样计算的:

  1. 创建一个空集合 E c E_c Ec
  2. 计算每个个体的适应度,与平均适应度的比值(下取整)
    f ‾ = ∑ i = 1 N f i q i = floor ( f i / f ‾ ) \begin{align*} &\overline f=\sum_{i=1}^Nf_i\\ &q_i=\text{floor}(f_i/\overline f) \end{align*} f=i=1Nfiqi=floor(fi/f)
  3. 对于每个个体 x i ∈ E x_i\in E xiE,复制 q i q_i qi倍,加入到 E c E_c Ec当中
  4. 返回 E c E_c Ec
2.2.2 交叉算子

E m = Crossover ( E c ) E_m=\text{Crossover}(E_c) Em=Crossover(Ec)的计算规则是这样的:

  1. 创建一个空集合 E m E_m Em
  2. 随机选取一个交叉点位 n ≤ 20 n\leq 20 n20
  3. 随机打乱 E c E_c Ec当中个体的排序,记打乱后的个体是 x i ′ x'_i xi
  4. 对于每一个 i = 1 , 3 , … , N − 1   o r   N − 2 i=1,3,\dots,N-1\ or\ N-2 i=1,3,,N1 or N2,进行概率为 p c p_c pc的二项决策,决定是否进行交叉
  5. 如果决定交叉,那么就将 x i ′ x'_{i} xi x i + 1 ′ x'_{i+1} xi+1 n n n到20位之间的二进制片段交换,得到 x ‾ i , x ‾ i + 1 \overline x_i,\overline x_{i+1} xi,xi+1
  6. 若不交换,则 x ‾ i , x ‾ i + 1 \overline x_i,\overline x_{i+1} xi,xi+1就是 x i ′ x'_{i} xi x i + 1 ′ x'_{i+1} xi+1
  7. x ‾ i , x ‾ i + 1 \overline x_i,\overline x_{i+1} xi,xi+1加入到 E m E_m Em
  8. 返回 E m E_m Em
2.2.3 变异算子

E = Mutation ( E m ) E=\text{Mutation}(E_m) E=Mutation(Em)是这样计算的:

  1. 创建空集合 E ′ E' E
  2. 对于每一个 i = 1 , 2 , … , N i=1,2,\dots,N i=1,2,,N,进行概率为 p m p_m pm的二项决策,决定是否进行变异
  3. 如果决定进行变异,则将个体 x ‾ i \overline x_i xi的每一位取反,得到 x ^ i \hat x_i x^i,否则 x ^ i = x ‾ i \hat x_i=\overline x_i x^i=xi
  4. x ^ i \hat x_i x^i加入到 E ′ E' E
  5. 返回 E = E ′ E=E' E=E

2.3 应用局部粒子群算法

参数:

  1. 粒子群规模: N = 50 N=50 N=50
  2. 学习因子: c 1 = 1.4 , c 2 = 1.7 c_1=1.4,c_2=1.7 c1=1.4,c2=1.7
  3. 自适应惯性因子: ω ( k ) \omega(k) ω(k).
    ω ( k ) = k G ( ω max − ω min ) \omega(k)=\frac{k}{G}(\omega_\text{max}-\omega_\text{min}) ω(k)=Gk(ωmaxωmin)
  4. 边界: V min = − 1 , V max = 1 , ω max = 0.1 , ω min = 0.9 V_\text{min}=-1,V_\text{max}=1, \omega_\text{max}=0.1, \omega_\text{min}=0.9 Vmin=1,Vmax=1,ωmax=0.1,ωmin=0.9

算法流程:

  1. 初始化粒子群 { ( x 1 , v 1 ) , … , ( x N , v N ) } \{(x_1,v_1),\dots,(x_N,v_N)\} {(x1,v1),,(xN,vN)},其中 x i x_i xi v i v_i vi都是20位的二进制串. 按照当前的粒子群分布,初始化历史最优值 p i , P i p_i,P_i pi,Pi,初始化粒子局部最优值最优值 s i , S i s_i, S_i si,Si,设置迭代次数 k = 1 k=1 k=1
  2. 对每个粒子更新速度 v i = ω ( k ) v i + c 1 r 1 ( P i − x i ) + c 2 r 2 ( S i − x i ) v_i=\omega(k)v_i+c_1r_1(P_i-x_i)+c_2r_2(S_i-x_i) vi=ω(k)vi+c1r1(Pixi)+c2r2(Sixi)
    r 1 r_1 r1 r 2 r_2 r2是随机采样的 ( 0 , 1 ) (0,1) (0,1)之间的值。对于超过区间 [ V min , V max ] [V_\text{min},V_\text{max}] [Vmin,Vmax]的值,取边界值。
  3. 对每个粒子更新位置 x i = x i + v i x_i=x_i+v_i xi=xi+vi
  4. 对每一个粒子 x i x_i xi,计算适应度 f i = f ( decode ( x i ) ) f_i=f(\text{decode}(x_i)) fi=f(decode(xi))
  5. 如果 f i > p i f_i>p_i fi>pi,则更新 p i = f i , P i = X i p_i=f_i, P_i=X_i pi=fi,Pi=Xi
  6. 计算每个粒子的局部最优值 s i , S i s_i, S_i si,Si
  7. 如果 k > G k>G k>G,终止。否则更新 k = k + 1 k=k+1 k=k+1并且回到2
  8. 取终止迭代时,粒子群中的最优粒子为算法的结果

2.4 应用差分进化算法

参数:

  1. 种群规模: N = 30 N=30 N=30
  2. 迭代次数: G = 50 G=50 G=50
  3. 变异因子: F = 1.2 F=1.2 F=1.2
  4. 交叉因子: c = 0.9 c=0.9 c=0.9

流程:

  1. 随机初始化种群 E = { x 1 , x 2 , … , x N } E=\{x_1,x_2,\dots,x_N\} E={ x1,x2,,xN},计算最优值 x b x_b xb和最优适应度 f b = f ( x b ) f_b=f(x_b) fb=f(xb),置迭代次数为 t = 0 t=0 t=0
  2. 对于每一个 x i x_i xi,随机选择 i ≠ r 1 ≠ r 2 ≠ r 3 i\neq r_1\neq r_2\neq r_3 i=r1=r2=r3,计算差分变异:

h i = x r 1 + F ( x r 2 − x r 3 ) h_i=x_{r_1}+F(x_{r_2}-x_{r_3}) hi=xr1+F(xr2xr3)

  1. 对于每一个 i , j i,j i,j,随机生成一个 λ ∈ ( 0 , 1 ) \lambda\in(0,1) λ(0,1),计算交叉子代矩阵

v i j = { h i j , λ < c x i j , λ ≥ c v_{ij}=\begin{cases} h_{ij},&\lambda<c\\ x_{ij},&\lambda\geq c \end{cases} vij={ hij,xij,λ<cλc

  1. 对于每一个 i i i,进行选择

x i = { x i , f ( x i ) ≥ f ( v i ) v i , f ( x i ) < f ( v i ) x_i=\begin{cases} x_i,&f(x_i)\geq f(v_i)\\ v_i,&f(x_i)<f(v_i) \end{cases} xi={ xi,vi,f(xi)f(vi)f(xi)<f(vi)

  1. 判断是否得到最大迭代次数,若是则终止迭代,否则置 t = t + 1 t=t+1 t=t+1
  2. 取终止迭代时群体中的最优个体作为算法的结果
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/FallenChild/article/details/131206713

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签