粒子群算法

算法概述

粒子群算法是根据鸟群觅食演化出的算法,我们的每个智能体相当于一只鸟,鸟的目标非常简单,就是要在食物最充足的地方安家,他们的策略是

1.每只鸟随机找一个地方,评估这个地方的食物量

2.所有的鸟一起开会,选出食物最多的地方作为候选点G

3.所有的鸟回顾自己的旅程,记住自己去过的食物最多的地方P

4.每只鸟为了找到食物量更多的地方,于是向着G飞行,但是呢,不知是出于选择困难症还是对P的留恋,或者是对G的不信任,小鸟向G飞行时,时不时也向P飞行,其实它自己也不知道到底是向G飞行的多还是向P飞行的多。

5.又到了开会的时间,如果小鸟们决定停止寻找,那么它们会选择当前的G来安家

算法流程

粒子群算法通过设计一种无质量的粒子来模拟鸟群中的鸟,粒子仅具有两个属性:速度和位置 ,速度代表移动的快慢,位置代表移动的方向。每个粒子在搜索空间中单独的搜寻最优解,并将其记为当前个体极值 ,并将个体极值与整个粒子群里的其他粒子共享,找到最优的那个个体极值作为整个粒子群的当前全局最优解 ,粒子群中的所有粒子根据自己找到的当前个体极值和整个粒子群共享的当前全局最优解来调整自己的速度和位置。粒子群算法的思想相对比较简单,主要分为

1、初始化粒子群

2、评价粒子,即计算适应值

3、寻找个体极值

4、寻找全局最优解

5、修改粒子的速度和位置。

更新速度和位置的公式

V i d = ω V i d + C 1 r a n d o m ( 0 , 1 ) ( P i d − X i d ) + C 2 r a n d o m ( 0 , 1 ) ( G i d − X i d ) % MathType!MTEF!2!1!+- % feaahqart1ev3aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLn % hiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYbItLDharqqtubsr % 4rNCHbWexLMBbXgBd9gzLbvyNv2CaeHbl7mZLdGeaGqiVu0Je9sqqr % pepC0xbbL8F4rqqrFfpeea0xe9Lq-Jc9vqaqpepm0xbba9pwe9Q8fs % 0-yqaqpepae9pg0FirpepeKkFr0xfr-xfr-xb9adbaqaaeGaciGaai % aabeqaamaabaabauaakeGabaaQpiaabAfadaWgaaWcbaGaamyAaiaa % dsgaaeqaaOGaeyypa0JaeqyYdCNaamOvamaaBaaaleaacaWGPbGaam % izaaqabaGccqGHRaWkcaWGdbWaaSbaaSqaaiaaigdaaeqaaOGaamOC % aiaadggacaWGUbGaamizaiaad+gacaWGTbGaaiikaiaaicdacaGGSa % GaaGymaiaacMcacaGGOaGaamiuamaaBaaaleaacaWGPbGaamizaaqa % baGccqGHsislcaWGybWaaSbaaSqaaiaadMgacaWGKbaabeaakiaacM % cacqGHRaWkcaWGdbWaaSbaaSqaaiaaikdaaeqaaOGaamOCaiaadgga % caWGUbGaamizaiaad+gacaWGTbGaaiikaiaaicdacaGGSaGaaGymai % aacMcacaGGOaGaam4ramaaBaaaleaacaWGPbGaamizaaqabaGccqGH % sislcaWGybWaaSbaaSqaaiaadMgacaWGKbaabeaakiaacMcaaaa!7005! {{\rm{V}}_{id}} = \omega {V_{id}} + {C_1}random(0,1)({P_{id}} - {X_{id}}) + {C_2}random(0,1)({G_{id}} - {X_{id}}) Vid=ωVid+C1random(0,1)(PidXid)+C2random(0,1)(GidXid)

X i d = X i d + V i d % MathType!MTEF!2!1!+- % feaahqart1ev3aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLn % hiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYbItLDharqqtubsr % 4rNCHbWexLMBbXgBd9gzLbvyNv2CaeHbl7mZLdGeaGqiVu0Je9sqqr % pepC0xbbL8F4rqqrFfpeea0xe9Lq-Jc9vqaqpepm0xbba9pwe9Q8fs % 0-yqaqpepae9pg0FirpepeKkFr0xfr-xfr-xb9adbaqaaeGaciGaai % aabeqaamaabaabauaakeaacaWGybWaaSbaaSqaaiaadMgacaWGKbaa % beaakiabg2da9iaadIfadaWgaaWcbaGaamyAaiaadsgaaeqaaOGaey % 4kaSIaamOvamaaBaaaleaacaWGPbGaamizaaqabaaaaa!49B8! {X_{id}} = {X_{id}} + {V_{id}} Xid=Xid+Vid

其中w为惯性因子,较大的w有利于全局搜索,较小的w有利于局部搜索,所以可以将w设置为递减的函数,C1和C2称为加速常数,一般取C1C2在0到4以内,random代表[0,1]的随机数,这两个随机数增加了算法的随机性,一定程度上避免了算法调入局部最优,Pid表示个体极值的第i个变量的第d维,Ggd表示全局最优解的第d维

实验

我们的测试函数是x*x + y*y,我们设置的区间是x属于[-10,10],y属于[-10,10],训练次数为100次

'''
@author:  LyaJpunov
@date:    2022年10月1日18:56:06
@purpose: 粒子群算法的演示
'''
import random

random.seed(9)

# 训练次数
epoch = 200
# 粒子个数
pos_number = 100
# 惯性因子w
w = 0.5
# 加速度常数c1 c2
c1 = 2
c2 = 2
# 历史上最好的适应度与粒子位置
best_fitness = float('-inf')
best_list = [0, 0]


class Pos():
    def __init__(self, x_, y_, v_x_, v_y_, max_x_, max_y_, max_v_x_, max_v_y_):
        self.x = x_
        self.y = y_
        self.v_x = v_x_
        self.v_y = v_y_
        self.max_x = max_x_
        self.max_y = max_y_
        self.max_v_x = max_v_x_
        self.max_v_y = max_v_y_

        # 最优的适应度
        self.max_fitness = float('-inf')
        # 最优适应度的x与y
        self.max_fitness_x = x_
        self.max_fitness_y = y_

    def __str__(self):
        return f"{self.x} - {self.y}"

    def update(self):
        global best_list
        global best_fitness
        self.v_x = w * self.v_x + c1 * random.random() * (self.max_fitness_x - self.x) + c2 * random.random() * (
                best_list[0] - self.x)
        self.v_y = w * self.v_y + c1 * random.random() * (self.max_fitness_y - self.y) + c2 * random.random() * (
                best_list[1] - self.y)
        if abs(self.v_x) > self.max_v_x:
            if self.v_x > 0:
                self.v_x = self.max_v_x
            else:
                self.v_x = - self.max_v_x
        if abs(self.v_y) > self.max_v_y:
            if self.v_y > 0:
                self.v_y = self.max_v_y
            else:
                self.v_y = - self.max_v_y
        self.x = self.x + self.v_x
        self.y = self.y + self.v_y
        if abs(self.x) > self.max_x:
            if self.x > 0 :
                self.x = self.max_x
            else:
                self.x = -self.max_x
        if abs(self.y) > self.max_y:
            if self.y > 0:
                self.y = self.max_y
            else:
                self.y = -self.max_y

        # 更新粒子的最佳适应度
        if fitness(self) > self.max_fitness:
            self.max_fitness = fitness(self)
            self.max_fitness_x = self.x
            self.max_fitness_y = self.y
            
        # 更新全局的最佳适应度
        if self.max_fitness > best_fitness:
            best_fitness = self.max_fitness
            best_list[0] = self.x
            best_list[1] = self.y


# 适应度函数,适应度函数的值越高,代表这个粒子越适合生存
def fitness(pos):
    return pos.x * pos.x + pos.y * pos.y

# 创建粒子并初始化
pos_list = []
for i in range(pos_number):
    pos_list.append(
        Pos(random.randint(-10, 10), random.randint(-10, 10), (random.random()-0.5) * 2, (random.random()-0.5) * 2, 10, 10, 2, 2))

# 初始化最初的粒子
for pos in pos_list:
    if fitness(pos) > best_fitness:
        best_x = pos.x
        best_y = pos.y

# 开始迭代
for i in range(epoch):
    for pos in pos_list:
        pos.update()

# 输出适应度最高的位置
print(best_list)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LyaJpunov

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值