粒子群算法求解多元函数最值问题

粒子群算法求解多元函数最值问题

一、简介

多元函数极值&最值问题通常使用导数/偏导数进行推导,这里尝试使用启发式算法进行求解近似最优解。选用粒子群算法进行求解,粒子群算法模仿鸟群觅食行为,核心思想是通过向距离食物最近的鸟集聚,不断更新速度和位置以达到最优解,即表现不好的个体通过向表现好的个体学习使得自身往好的方向转变,这里存在一个前提:所有鸟知道距离食物的远近,距离食物最近包含两部分:当前最近和历史最近。标准粒子群算法适合求解函数极值问题,在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  # 社会认知因子
    # pBest, pLine = 0, []  # 当前最优值、当前最优解,(自我认知部分)
    # gBest, gLine = 0, []  # 全局最优值、全局最优解,(社会认知部分)
    v_low = -2 #速度约束
    v_high =2
    iterMax = 100  # 迭代次数
    iterI = 1  # 当前迭代次数
    bestfit = -100000  # 记录每代最优值
    #y = (x1+x2)/(x1**2+x2**2+1)
    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
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值