WCO,即世界杯优化算法(World Cup Optimization),是2016年提出的算法,这个算法的提出,充分说明了动物不够用了,人们开始通过人群来研究群体智能了。
在WCO中,最基本的抽象就是洲、国家以及参赛球队。其中,国家表示一组独立的参数,参赛球队则是单个参数。即
C={x⃗i}C=\{\vec x_i\} C={xi}
x⃗i\vec x_ixi就是参赛国,其每个分量,都代表一个球队,许多个参赛国共同组成一个大洲。
在优化过程中,优化参数是肯定要相等的,也就是说每个国家都有相同数目的候选团队;同时每个洲又都有相同数目的参赛国家,从而每个大洲的球队可以通过矩阵表示,故将第kkk个大洲的第iii个国家的第jjj个球队记作
xkij∈Ckx_{ki}^j\in C_k xkij∈Ck
每个国家的所有球队放在一起,组成一个参数数组,带入到判定函数中,得到对应的适应度
fki=f(xki)f_{ki} = f(x_{ki}) fki=f(xki)
接下来开始球队之间的竞争,主要分为三个步骤
1 设总共有NNN个大洲,计算各大洲适应度的平均值和标准差
−∷k=∑infkiNσk=∑i=1nfki−μkN−1\minuscoloncolon_k=\sum^n_i\frac{f_{ki}}{N}\\ \sigma_k = \sqrt{\sum^n_{i=1}\frac{f_{ki}-\mu_k}{N-1}} −::k=i∑nNfkiσk=i=1∑nN−1fki−μk
2 计算各大洲分数
Rk=randσk+μk2R_k=\frac{\operatorname{rand}\sigma_k+\mu_k}{2} Rk=2randσk+μk
其中,rand是用于调节步长的随机数,取值范围是(0,1)(0,1)(0,1),计算得到的RkR_kRk值将用于排序。
3 至此,其实就可以得到最佳球队了,冠军就是fff值最小的那个。
但接下来才是算法的关键之处,也是玄幻之处。首先,根据RkR_kRk的值,对所有大洲进行排序
X1=[X11,⋯,X1n]X2=[X21,⋯,X2n]⋮Xm=[Xm1,⋯,Xmn]\begin{aligned} X_1 &= \begin{bmatrix}X_{11},&\cdots,&X_{1n}\end{bmatrix}\\ X_2 &= \begin{bmatrix}X_{21},&\cdots,&X_{2n}\end{bmatrix}\\ &\vdots\\ X_m &= \begin{bmatrix}X_{m1},&\cdots,&X_{mn}\end{bmatrix}\\ \end{aligned} X1X2Xm=[X11,⋯,X1n]=[X21,⋯,X2n]⋮=[Xm1,⋯,Xmn]
然后,把排名第一的大洲X1X_1X1提取出来,作为下次参赛内定的成员。这个意图很明显,X1X_1X1在本次世界杯比赛中表现最佳,说明X1X_1X1的各参赛国的球队,下次参加比赛只需微调就行;其他大洲表现不佳,说明派来的球队不佳,所以需要更换球队。
所以,下一次参加世界杯的国家包括两部分,即XbestX_{best}Xbest和XrandX_{rand}Xrand,二者都有一定的随机性,区别在于,后者就按照初始化时那样随机生成就行,前者则需根据X1X_1X1的值进行限定。
记Ub=max(X1),Lb=min(X1)U_b=\max(X_1), L_b=\min(X_1)Ub=max(X1),Lb=min(X1),令U=12δ(Ub+Lb),L=12δ(Ub−Lb)U=\frac{1}{2}\delta(U_b+L_b), L=\frac{1}{2}\delta(U_b-L_b)U=21δ(Ub+Lb),L=21δ(Ub−Lb),则XbestX_{best}Xbest的生成区间为
L 最后,不符合现实的魔幻设定也出现了,各参赛国可以自行选择自己的洲,相当于将[Xbest,Xrand][X_{best},X_{rand}][Xbest,Xrand]打乱重排。 通过不断迭代上述的步骤,就完成了球队的更新和进化。 首先,实现其迭代逻辑 然后,实现迭代流程 最后,做个函数测试一下 效果为Python实现
import numpy as np
from itertools import chain
from random import shuffle
rand = np.random.rand
uniRand = np.random.uniform# 表示
# cs 表示各大洲,每个大洲都是一个矩阵
# 设K个大洲,每个大洲M个国家,每个国家N个球队
def compi(cs, func):# fs为适应度函数,为KxM维矩阵fs = [[func(x) for x in xs] for xs in cs] mu = np.array([np.mean(f) for f in fs]) # 各大洲平均值sigma = np.array([np.std(f) for f in fs]) # 各大洲标准差rs = (rand(len(mu))*sigma + mu)/2fBest = np.min(fs)i,j = np.where(np.array(fs)==fBest)best = [fBest, cs[i[0]][j[0]]]return cs[np.argmin(rs)], best
# func为优化函数;
# K为大洲个数;M为每个洲的国家数;N为每个国家的球队数;
# xRange为求解范围,nIter为迭代次数
# ac用于调控最优值精度
def wco(func, K, M, N, xRange, nIter, ac=0.5):cs = [uniRand(*xRange, N) for _ in range(K*M)]cs = np.array(cs).reshape(K,M,N)for _ in range(nIter):xBest, best = compi(cs, func)xL = np.min(xBest, axis=0)xR = np.max(xBest, axis=0)xL, xR = ac*(xR-xL)/2, ac*(xR+xL)/2xBest = [uniRand(xL, xR) for _ in range(M)]xRand = [uniRand(*xRange, N) for _ in range((K-1)*M)]cs = xBest + xRandlen(cs)shuffle(cs)cs = np.array(cs).reshape(K,M,N)msg = f"最佳值为{best[0]}, 参数为" msg += ", ".join([f"{x:.6f}" for x in best[1]])print(msg)
def test(xs):_sum = 0.0for i in range(len(xs)):_sum = _sum + np.cos((xs[i]*i)/5)*(i+1)return _sumif __name__ == "__main__":cNum = [15,20,100]s = wco(test, 20, 32, 5, (-20,20), 200)
>python wco.py
最佳值为-12.3236101211265, 参数为-11.129479, -14.625573, -8.625970, 15.884463, -3.383388
上一篇:Linux内核中ideapad-laptop.c文件全解析5
下一篇:访问nginx报错502日志:failed (13: Permission denied) while connecting to upstream