粒子群算法求解多元函数最值问题
一、简介
多元函数极值&最值问题通常使用导数/偏导数进行推导,这里尝试使用启发式算法进行求解近似最优解。选用粒子群算法进行求解,粒子群算法模仿鸟群觅食行为,核心思想是通过向距离食物最近的鸟集聚,不断更新速度和位置以达到最优解,即表现不好的个体通过向表现好的个体学习使得自身往好的方向转变,这里存在一个前提:所有鸟知道距离食物的远近,距离食物最近包含两部分:当前最近和历史最近。标准粒子群算法适合求解函数极值问题,在TSP、背包问题上多用混合型粒子群算法。算法详细介绍可参考【粒子群算法研究】。
二、粒子群算法求解
多元函数:y = (
x
1
x_1
x1?+
x
2
x_2
x2?)/(
x
1
2
x_1^2
x12?+
x
2
2
x_2^2
x22?+1)
粒子群编程求解
import pylab as mpl
import random import
matplotlib.pyplot as plt
mpl.rcParams['font.sans-serif'] = ['SimHei']
def fitness(x):
"""
计算适应值:y = (x1+x2)/(x1**2+x2**2+1)
"""
x1 = x[0]
x2 = x[1]
y = (x1+x2)/(x1**2+x2**2+1)
return y
def update(x, p, g, w, c1, c2, v_low, v_high, vi, d, x_low, x_up):
'''
更新速度和位置
'''
vi = w * vi + c1 * random.uniform(0, 1) * (p-x) + c2 * random.uniform(0, 1) * (g-x)
for j in range(d):
if vi[j] >v_high:
vi[j] = v_high
elif vi[j] < v_low:
vi[j] = v_low
x = x +vi
for j in range(d):
if x[j] > x_up[j]:
x[j] = x_up[j]
elif x[j] < x_low[j]:
x[j] = x_low[j]
return x
if __name__ == '__main__':
birdNum = 20
w = 0.2
c1 = 0.4
c2 = 0.4
v_low = -2
v_high =2
iterMax = 100
iterI = 1
bestfit = -100000
d = 2
x_low = [-10, -10]
x_up = [10, 10]
xs = np.array([np.array([random.uniform(x_low[0],x_up[0]),random.uniform(x_low[1],x_up[1])])
for i in range(birdNum)])
v = np.array([random.uniform(v_low,v_high) for i in range(birdNum)])
fits = np.array([fitness(x) for x in xs])
fit = max(fits)
x = xs[np.argmax(fits)]
gBest = pBest = fit
gSolve = pSolve = x
bestfit = []
bestfit.append(gBest)
while iterI <= iterMax:
for i in range(birdNum):
xs[i] = update(xs[i], pSolve, gSolve, w, c1, c2, v_low, v_high, v[i], d, x_low, x_up)
fits[i] = fitness(xs[i])
pBest, pSolve = max(fits), xs[np.argmax(fits)]
if max(fits) >= gBest:
gBest, gSolve = max(fits), xs[np.argmax(fits)]
bestfit.append(gBest)
print(iterI, gBest)
print(gSolve, pSolve)
iterI += 1
plt.plot(range(1,len(bestfit)+1), bestfit)
plt.xlabel("迭代次数")
plt.ylabel("最优值")
plt.show()
结果
y
y
y=0.7068,
x
1
=
0.8701
,
x
2
=
0.8287
x_1=0.8701,x_2=0.8287
x1?=0.8701,x2?=0.8287
|