智能计算粒子群算法python版本,带详细注释

今天不会,问ai给的,自己慢慢的解释了代码,现在明白了,但是不会写,看还是能看懂的

import random
import matplotlib.pyplot as plt
import numpy as np


class Particle:
    def __init__(self, x, y, vx, vy):
        # [x,y] pos结果 [-10,10]  x,y 的位置
        self.pos = np.array([x, y])  # 粒子的位置
        #[-10,10] vel x,y方向的速度 相当与速度分解了
        self.vel = np.array([vx, vy])  # 粒子的速度
        self.best_pos = self.pos  # 粒子最好的位置
        self.best_score = None  # 粒子最好的适应度值

    def update_position(self):
        #两个数组相加 数组里面一对一相加 [1,2]+[3,4]=[4,6] 然后复制pos 相当于位置加速度 得到新的位置
        self.pos += self.vel
    #第二个参数的要解决问题的函数  该函数两个参数是x,y 可以表示一个点
    def evaluate_score(self, fitness_func):
        #score 是一个元组里面有一个数把x**2+y**2 的结果 这个也算适应度
        score = fitness_func(*self.pos)
        #如果这次的位置比之前的位置要好,就把这个记下来 适应度也记录下面
        if self.best_score is None or score > self.best_score:
            self.best_pos = self.pos
            self.best_score = score


class PSO:
    def __init__(self, num_particles, range_x, range_y, fitness_func, weight, learning_rate, c1, c2):
        #粒子数量
        self.num_particles = num_particles
        #粒子位置 x,y 元组
        self.range_x = range_x
        #粒子速度 x,y 分量
        self.range_y = range_y
        #优化的目标函数
        self.fitness_func = fitness_func
        # 权重
        self.weight = weight
        #学习因子 控制粒子的速度变化的幅度
        self.learning_rate = learning_rate
        self.c1 = c1
        self.c2 = c2
        #在[-10,10] 生成一个数 x ,y   速度都是0  然后一次生成了50个粒子 [0,50)
        self.particles = [Particle(random.uniform(range_x[0], range_x[1]), random.uniform(range_y[0], range_y[1]), 0, 0)
                          for _ in range(num_particles)]
        #粒子群最好的位置
        self.gbest_pos = None
        #粒子群的最好位置对应的适应度
        self.gbest_score = None
        #存储粒子群的历史最优解
        self.history = []
    #遍历每个粒子并计算对目标函数的适应度 然后 从中找到一个最优的粒子 作为粒子群的最优位置和最优适应度
    def evaluate_fitness(self):
        #遍历粒子
        for particle in self.particles:
            #算粒子的对目标函数的适应度 粒子会判断这次的位置和自己的历史位置,哪个最好,最好就记录下来,位置和适应度
            particle.evaluate_score(self.fitness_func)
            #因为第一次是None 不得不这么写 ,判断粒子的最优适应度是否比种群的适应度要大?
            if self.gbest_score is None or particle.best_score > self.gbest_score:
                #如果有最优的,就更新 并记录下适应度
                self.gbest_pos = particle.best_pos
                self.gbest_score = particle.best_score
    #移动粒子
    def update_particles(self):
        #遍历粒子
        for particle in self.particles:
            #生成[0,1]之间的随机数 r1控制个体的位置  r2控制群体的位置  r1 和 r2 来影响粒子的搜索方向和速度调整,但是这种影响是间接的
            r1 = random.uniform(0, 1)
            r2 = random.uniform(0, 1)
            #使用公式计算粒子要移动的速度 不知道这种公式是如何想出来的 particel.vel是一个numpy的列表 [x,y] 这样的  best_pos和pos一样 [x,y] 也是numpy的

            particle.vel = self.weight * particle.vel + self.c1 * r1 * (
                        particle.best_pos - particle.pos) + self.c2 * r2 * (self.gbest_pos - particle.pos)
            #该循环上面完成了速度计算 下面两行是限制速度的,可能超过最大速度和低于最小速度
            # 可以枚举,比如如果比learning_rate还小 或者还大,最终的结果一定是[-self.learning_rate,self.learning_rate]
            #速度变化不可以超过0.1 不可低于-0.1
            particle.vel[0] = max(-self.learning_rate, min(particle.vel[0], self.learning_rate))
            particle.vel[1] = max(-self.learning_rate, min(particle.vel[1], self.learning_rate))
            #至此 循环完整了 合法的速度 速度没有问题了,然后更新位置,就会用我们最新的速度去移动了,得到新的位置
            particle.update_position()
            # 确保粒子位置在指定范围内 x,y 坐标不可以超过范围-10 到10 以确保在搜索空间内搜索 其它以外不要
            particle.pos[0] = max(self.range_x[0], min(particle.pos[0], self.range_x[1]))
            particle.pos[1] = max(self.range_y[0], min(particle.pos[1], self.range_y[1]))
            #至此完成了位置的限制 速度和位置都完成了 依次重复即可
    def run(self, num_iterations):
        #开始迭代(每次迭代全部粒子移动一次) 不断求适应度,然后记录最优值 ,然后移动 ,这样重复
        for i in range(num_iterations):
            #遍历每个粒子并求适应度,然后找到最优秀的作为粒子群的最优粒子,然后记录下来
            self.evaluate_fitness()
            #计算速度,修正速度超出范围,然后移动,更新位置
            self.update_particles()
            #记录最优秀粒子
            self.history.append(self.gbest_score)
            #每迭代10次就输出一次目前最优的粒子
            if i % 10 == 0:
                print("Iteration {}: Best Score = {}".format(i, self.gbest_score))

        print("Optimization finished.")
        print("Best solution found at:")
        #最优的位置
        print(self.gbest_pos)
        print("Best score:")
        #对应的适应度
        print(self.gbest_score)

        # 绘制适应度值历史记录
        plt.plot(self.history)
        plt.title("Fitness Value History")
        plt.xlabel("Iteration")
        plt.ylabel("Fitness Value")
        plt.show()

# 定义一个二维函数作为优化目标
def fitness_func(x, y):
    return (x**2 + y**2)

# 创建一个PSO对象并运行算法
#粒子的数量,粒子x范围位置(只能在这个区域搜索),后面在这个范围里面得到一个随机数  粒子y范围  优化的目标函数
# 惯性权重(控制当前迭代中速度对下一代的运动状态的影响程度) 学习因子(粒子速度更新幅度)  c1控制自身位置对速度的影响程度  c2同理
pso = PSO(num_particles=50, range_x=(-10, 10), range_y=(-10, 10), fitness_func=fitness_func, weight=1, learning_rate=0.1, c1=0.5, c2=0.5)
#迭代次数
pso.run(num_iterations=100)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值