073. 编写一个函数,实现简单的粒子群优化算法
粒子群优化算法(Particle Swarm Optimization, PSO)是一种基于群体智能的优化算法,模拟鸟类群体的社会行为来寻找最优解。PSO 通常用于连续优化问题,通过粒子的协作和信息共享来搜索解空间。 以一个简单的优化问题为例:最小化一个二维函数 f(x,y)=x2+y2。
示例
假设我们要最小化函数 f(x,y)=x2+y2,其中 x 和 y 是实数,范围在 [−10,10] 之间。
粒子群优化算法的基本步骤
- 初始化:随机生成一组粒子,并初始化它们的位置和速度。
- 适应度评估:计算每个粒子的适应度(目标函数值)。
- 更新个体最优解和全局最优解:每个粒子记录自己的最优位置和整个群体的最优位置。
- 更新速度和位置:根据个体最优解和全局最优解更新每个粒子的速度和位置。
- 迭代:重复上述步骤,直到满足终止条件(如达到最大迭代次数)。
示例代码
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
注意事项
- 参数调整:粒子数量、惯性权重 w、个体学习因子 c1 和社会学习因子 c2 等参数对算法性能有重要影响,需要根据具体问题进行调整。
- 边界处理:在更新位置后,需要确保粒子位置在合法范围内。可以通过
np.clip
函数限制粒子位置。 - 适应度函数:根据具体问题定义适应度函数。对于最小化问题,适应度函数通常是目标函数本身;对于最大化问题,可以使用目标函数的负值。
- 性能优化:对于大规模问题,可以使用并行计算或优化数据结构来提高算法性能。
视频讲解
BiliBili: 视睿网络-哔哩哔哩视频 (bilibili.com)