073. 编写一个函数,实现简单的粒子群优化算法

粒子群优化算法(Particle Swarm Optimization, PSO)是一种基于群体智能的优化算法,模拟鸟类群体的社会行为来寻找最优解。PSO 通常用于连续优化问题,通过粒子的协作和信息共享来搜索解空间。 以一个简单的优化问题为例:最小化一个二维函数 f(x,y)=x2+y2。

示例

假设我们要最小化函数 f(x,y)=x2+y2,其中 x 和 y 是实数,范围在 [−10,10] 之间。

粒子群优化算法的基本步骤

  1. 初始化:随机生成一组粒子,并初始化它们的位置和速度。
  2. 适应度评估:计算每个粒子的适应度(目标函数值)。
  3. 更新个体最优解和全局最优解:每个粒子记录自己的最优位置和整个群体的最优位置。
  4. 更新速度和位置:根据个体最优解和全局最优解更新每个粒子的速度和位置。
  5. 迭代:重复上述步骤,直到满足终止条件(如达到最大迭代次数)。

示例代码

import numpy as np

# 目标函数
def objective_function(x):
    return x[0]**2 + x[1]**2

# 粒子群优化算法
def particle_swarm_optimization(num_particles, num_dimensions, num_iterations, bounds, w=0.5, c1=1.5, c2=1.5):
    """
    粒子群优化算法

    :param num_particles: 粒子数量
    :param num_dimensions: 搜索空间的维度
    :param num_iterations: 迭代次数
    :param bounds: 每个维度的边界 (min, max)
    :param w: 惯性权重
    :param c1: 个体学习因子
    :param c2: 社会学习因子
    :return: 最优解和最优值
    """
    # 初始化粒子位置和速度
    particles = np.random.uniform(low=bounds[0], high=bounds[1], size=(num_particles, num_dimensions))
    velocities = np.random.uniform(low=-1, high=1, size=(num_particles, num_dimensions))

    # 初始化个体最优解和全局最优解
    personal_best_positions = particles.copy()
    personal_best_scores = np.apply_along_axis(objective_function, 1, particles)
    global_best_position = particles[np.argmin(personal_best_scores)]
    global_best_score = np.min(personal_best_scores)

    for iteration in range(num_iterations):
        for i in range(num_particles):
            # 更新速度
            r1, r2 = np.random.rand(num_dimensions), np.random.rand(num_dimensions)
            velocities[i] = (w * velocities[i] +
                             c1 * r1 * (personal_best_positions[i] - particles[i]) +
                             c2 * r2 * (global_best_position - particles[i]))

            # 更新位置
            particles[i] += velocities[i]

            # 限制粒子位置在边界内
            particles[i] = np.clip(particles[i], bounds[0], bounds[1])

            # 评估新位置的适应度
            score = objective_function(particles[i])

            # 更新个体最优解
            if score < personal_best_scores[i]:
                personal_best_positions[i] = particles[i].copy()
                personal_best_scores[i] = score

                # 更新全局最优解
                if score < global_best_score:
                    global_best_position = particles[i].copy()
                    global_best_score = score

        print(f"Iteration {iteration + 1}: Best Score = {global_best_score:.4f}")

    return global_best_position, global_best_score

# 示例用法
if __name__ == "__main__":
    num_particles = 30  # 粒子数量
    num_dimensions = 2  # 搜索空间维度
    num_iterations = 100  # 迭代次数
    bounds = (-10, 10)  # 每个维度的边界

    best_position, best_score = particle_swarm_optimization(num_particles, num_dimensions, num_iterations, bounds)
    print(f"Best Position: {best_position}")
    print(f"Best Score: {best_score:.4f}")

代码说明

目标函数:定义了一个简单的目标函数 f(x,y)=x2+y2。

初始化:随机生成粒子的位置和速度。位置在指定的边界内随机初始化,速度在 [−1,1] 之间随机初始化。

适应度评估:使用 np.apply_along_axis 计算每个粒子的适应度。

更新速度和位置

  • 根据 PSO 的更新公式更新每个粒子的速度和位置。

  • 使用 np.clip 限制粒子位置在边界内。

更新个体最优解和全局最优解

  • 每个粒子记录自己的最优位置(personal_best_positions)和适应度(personal_best_scores)。

  • 更新全局最优位置(global_best_position)和适应度(global_best_score)。

迭代:重复上述步骤,直到达到最大迭代次数。

示例输出

Iteration 1: Best Score = 123.4567
Iteration 2: Best Score = 98.7654
...
Iteration 100: Best Score = 0.0001
Best Position: [0.0001 0.0001]
Best Score: 0.0001

注意事项

  1. 参数调整:粒子数量、惯性权重 w、个体学习因子 c1 和社会学习因子 c2 等参数对算法性能有重要影响,需要根据具体问题进行调整。
  2. 边界处理:在更新位置后,需要确保粒子位置在合法范围内。可以通过 np.clip 函数限制粒子位置。
  3. 适应度函数:根据具体问题定义适应度函数。对于最小化问题,适应度函数通常是目标函数本身;对于最大化问题,可以使用目标函数的负值。
  4. 性能优化:对于大规模问题,可以使用并行计算或优化数据结构来提高算法性能。

视频讲解

BiliBili: 视睿网络-哔哩哔哩视频 (bilibili.com)