优化算法:2.粒子群算法(PSO)及Python实现

一、定义

        粒子群算法(Particle Swarm Optimization,PSO)是一种模拟鸟群觅食行为的优化算法。想象一群鸟在寻找食物,每只鸟都在尝试找到食物最多的位置。它们通过互相交流信息,逐渐向食物最多的地方聚集。PSO就是基于这种群体智能的原理。

二、过程

        1. 初始化粒子群

        首先,我们随机生成一群粒子,每个粒子代表一个潜在的解。这些粒子就像一群鸟,它们在问题的解空间中随机分布。每个粒子有自己的位置和速度,位置表示解的参数,速度表示解的变化趋势。

        设粒子群大小为  n,粒子的位置和速度用向量表示。假设搜索空间是 d 维的。

  • 位置初始化:每个粒子的初始位置 x_i可以随机生成在搜索空间的范围内:

    x_{i,j} = x_{\text{min},j} + \text{rand()} \times (x_{\text{max},j} - x_{\text{min},j})

    其中, x_{\text{min},j}x_{\text{max},j} 分别是第 j 维的最小值和最大值,rand() 是一个生成 [0, 1] 之间随机数的函数。

  • 速度初始化:每个粒子的初始速度 v_i也可以随机生成:

    v_{i,j} = v_{\text{min},j} + \text{rand()} \times (v_{\text{max},j} - v_{\text{min},j})

    其中, v_{\text{min},j}v_{\text{max},j}分别是第 j 维的最小速度和最大速度。

        2. 计算适应度

        每个粒子都有一个“适应度”,这就像是鸟找到的食物量。适应度越高,表示解越好。我们用一个函数来计算每个粒子的适应度,这个函数通常是我们要优化的问题的目标函数。

        计算每个粒子当前的位置 x_i  对应的适应度值 f(x_i) ,以衡量其解的好坏。这个适应度函数 f 就是我们要优化的目标函数,具体形式取决于实际问题。

        3. 更新个体和全局最佳位置

        每个粒子都记得自己找到的最好的位置(个体最佳位置 p_i ​),这叫做“个体最佳位置”。同时,所有粒子中找到的最好的位置叫做“全局最佳位置”(全局最佳位置 g)。在每次迭代中,我们检查每个粒子的当前位置是否比它之前找到的最好位置更好,如果是,就更新个体最佳位置。同时,我们也更新全局最佳位置。

        在优化问题中,我们通常有一个目标函数 f(x),其目的是要最小化或最大化这个函数。适应度函数 f(x) 是一个评估每个解好坏的函数。在最小化问题中,适应度函数值越小,表示这个解越好;而在最大化问题中,适应度函数值越大,表示这个解越好。

  • 个体最佳位置更新:对于每个粒子,如果当前适应度值更好,则更新个体最佳位置:

    如果 f(x_i) < f(p_i) ,则 p_i = x_i。其中, p_i ​ 是第 i 个粒子的个体最佳位置。

  • 全局最佳位置更新:检查所有粒子的个体最佳位置,找到适应度值最小(此处假设为最大化问题)的那个位置作为全局最佳位置:g = \arg \min_{p_i} f(p_i)。其中,g 是全局最佳位置。

        4. 更新速度和位置

        更新速度

        每个粒子的速度更新公式如下:

v_{i,j}(t+1) = w \cdot v_{i,j}(t) + c_1 \cdot \text{rand()} \cdot (p_{i,j} - x_{i,j}(t)) + c_2 \cdot \text{rand()} \cdot (g_j - x_{i,j}(t))

        其中:

  • v_{i,j}(t)是第 i 个粒子在第 j 维上的当前速度。
  • w 是惯性权重,控制粒子保持原有速度的程度。
  • c_1是认知系数,控制粒子向自身历史最佳位置移动的程度。
  • c_2是社会系数,控制粒子向全局最佳位置移动的程度。
  • \text{rand()} 是一个生成 [0, 1]之间随机数的函数。
  • p_{i,j}是第 i 个粒子在第 j 维上的个体最佳位置。
  • g_j 是全局最佳位置在第 j 维上的值。
  • x_{i,j}(t)是第 i 个粒子在第 j 维上的当前位置。

        更新位置:

        每个粒子的位置更新公式如下:

        x_{i,j}(t+1) = x_{i,j}(t) + v_{i,j}(t+1)

        其中:

  • x_{i,j}(t)是第 i 个粒子在第 j 维上的当前位置。
  • v_{i,j}(t+1) 是第 i 个粒子在第 j 维上的更新后的速度。

5. 重复迭代

        我们重复上述步骤,直到满足某个停止条件,比如达到最大迭代次数,或者粒子的适应度变化很小。

三、Python示例

  1. 目标函数:定义了一个简单的目标函数f(x, y) = x^2 + y^2
  2. 参数设置:设置了PSO算法的参数,包括粒子数量、迭代次数、惯性权重和认知/社会系数。
  3. 初始化:初始化了粒子的位置和速度,同时记录每个粒子的个体最佳位置和全局最佳位置。
  4. 迭代优化:在每次迭代中,更新粒子的速度和位置,更新个体最佳位置和全局最佳位置,记录全局最佳位置的历史。
  5. 理论结果:定义的目标函数f(x, y) = x^2 + y^2 中,全局最优解显然是 (x, y) = (0, 0),因为这是函数的最小值点,其值为0。全局最佳位置的移动轨迹应该表现为逐步接近原点 (0, 0)的过程。

        完整代码如下:

import numpy as np
import matplotlib.pyplot as plt


# 定义目标函数(f(x) = x^2 + y^2)
def objective_function(position):
    return position[0] ** 2 + position[1] ** 2


# 参数
num_particles = 30  # 粒子数量,即搜索空间中的粒子数
num_iterations = 100  # 迭代次数,即算法运行的总次数
w = 0.7  # 惯性权重,控制粒子速度的惯性
c1 = 1.5  # 认知系数
c2 = 1.5  # 社会系数

# 初始化粒子位置和速度
particles_position = np.random.uniform(-10, 10, (num_particles, 2))  # 随机初始化粒子的位置,范围在 [-10, 10] 之间
particles_velocity = np.random.uniform(-1, 1, (num_particles, 2))  # 随机初始化粒子的速度,范围在 [-1, 1] 之间
personal_best_position = particles_position.copy()
personal_best_value = np.array([objective_function(p) for p in particles_position])
global_best_position = personal_best_position[np.argmin(personal_best_value)]
global_best_value = np.min(personal_best_value)

# 记录优化过程中的全局最佳位置
global_best_positions_history = []

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

        # 更新位置
        particles_position[i] += particles_velocity[i]

        # 更新个体最佳位置
        current_value = objective_function(particles_position[i])
        if current_value < personal_best_value[i]:
            personal_best_value[i] = current_value
            personal_best_position[i] = particles_position[i]

    # 更新全局最佳位置
    current_best_value = np.min(personal_best_value)
    if current_best_value < global_best_value:
        global_best_value = current_best_value
        global_best_position = personal_best_position[np.argmin(personal_best_value)]

    # 记录全局最佳位置
    global_best_positions_history.append(global_best_position.copy())

# 绘制结果
global_best_positions_history = np.array(global_best_positions_history)
plt.figure(figsize=(10, 6))
plt.plot(global_best_positions_history[:, 0], global_best_positions_history[:, 1], 'bo-', label='Global Best Position',
         zorder=1)
plt.scatter(global_best_positions_history[-1, 0], global_best_positions_history[-1, 1], color='red', s=50,
            label='Final Global Best', zorder=2)
plt.text(global_best_positions_history[-1, 0], global_best_positions_history[-1, 1],
         f'({global_best_positions_history[-1, 0]:.2f}, {global_best_positions_history[-1, 1]:.2f})',
         color='red', fontsize=12, zorder=3)
plt.title('PSO Optimization Process')
plt.xlabel('X Position')
plt.ylabel('Y Position')
plt.legend()
plt.grid()
plt.show()

        结果如下:

  • 11
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的粒子群优化算法Python实现代码。请注意,这只是一个示例,可以根据特定问题进行修改。 ```python import random # 定义问题,目标函数为 x^2 def objective_function(x): return x ** 2 # 定义粒子类 class Particle: def __init__(self, dims): self.position = [random.uniform(-5.0, 5.0) for _ in range(dims)] self.velocity = [0.0 for _ in range(dims)] self.best_position = self.position self.best_score = float('inf') def update_velocity(self, global_best_position, omega, phi_p, phi_g): for i in range(len(self.velocity)): r_p = random.random() r_g = random.random() cognitive = phi_p * r_p * (self.best_position[i] - self.position[i]) social = phi_g * r_g * (global_best_position[i] - self.position[i]) self.velocity[i] = omega * self.velocity[i] + cognitive + social def update_position(self): for i in range(len(self.position)): self.position[i] += self.velocity[i] def evaluate(self): score = objective_function(self.position) if score < self.best_score: self.best_position = self.position self.best_score = score # 定义PSO算法类 class PSO: def __init__(self, dims, num_particles, max_iter): self.dims = dims self.num_particles = num_particles self.max_iter = max_iter self.particles = [Particle(dims) for _ in range(num_particles)] self.global_best_position = self.particles[0].position self.global_best_score = float('inf') def optimize(self): for i in range(self.max_iter): for particle in self.particles: particle.evaluate() if particle.best_score < self.global_best_score: self.global_best_position = particle.best_position self.global_best_score = particle.best_score for particle in self.particles: particle.update_velocity(self.global_best_position, 0.5, 0.5, 0.5) particle.update_position() # 使用示例 pso = PSO(1, 10, 100) pso.optimize() print(pso.global_best_position) ``` 这里我们定义了一个简单的目标函数 `objective_function`,它的实现是 $x^2$。然后我们定义了一个 `Particle` 类来表示粒子,其中包括位置、速度、最佳位置和最佳得分。然后我们定义了一个 `PSO` 类来表示整个算法,其中包括粒子群、最大迭代次数和全局最佳位置和最佳得分。 在 `optimize` 方法中,我们首先遍历所有粒子并评估它们的得分。如果某个粒子的最佳得分比全局最佳得分更好,则更新全局最佳位置和最佳得分。然后我们再次遍历所有粒子,并更新它们的速度和位置。 最后,我们可以使用 `PSO` 类来解决特定问题。在这个示例中,我们使用 `PSO(1, 10, 100)` 来寻找一个一维函数的最小值,其中有10个粒子,最大迭代次数为100。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值