本研究对比分析了四种粒子群优化(PSO)算法变体在求解Schwefel's P2.21函数优化问题上的性能,包括标准PSO(SPSO)、自适应PSO(APSO)、改进的带变异PSO(IPSOM)和混合PSO(HPSO)。通过实验表明,在该特定问题上,APSO算法在收敛速度和解的质量方面都展现出了较好的性能。本研究为PSO算法在类似优化问题中的选择和应用提供了参考依据。
粒子群优化(PSO)算法作为一种群智能优化方法,因其实现简单、参数少等特点在连续优化问题中得到广泛应用。然而,标准PSO算法存在易陷入局部最优、收敛速度不稳定等问题。为此,研究者提出了多种改进策略,形成了不同的PSO变体。
本研究旨在通过在Schwefel's P2.21函数这一典型测试函数上的实验对比,评估不同PSO变体的性能特点,为实际应用中的算法选择提供依据。
Schwefel's P2.21函数定义如下:
其中:
处
标准PSO采用固定的惯性权重和学习因子,其速度更新公式为:
APSO通过动态调整惯性权重和学习因子,适应优化过程的不同阶段:
IPSOM引入高斯变异操作,增强种群多样性:
if rand() >= pm:
标准PSO更新
else:
x = x + N(0, σ)HPSO结合差分进化策略,增强全局搜索能力:
if rand() < cr:
v = w * v + F * (x1 - x2) + c1 * r1 * (pbest - x) + c2 * r2 * (gbest - x)

实验结果统计如下:
算法 | 最优值 | 平均值 | 标准差 |
|---|---|---|---|
SPSO | 3.24e-05 | 5.67e-05 | 2.43e-05 |
APSO | 1.15e-05 | 2.89e-05 | 1.74e-05 |
IPSOM | 2.78e-05 | 4.92e-05 | 2.14e-05 |
HPSO | 1.93e-05 | 3.76e-05 | 1.83e-05 |
SPSO:表现稳定但容易早熟收敛APSO:整体性能最优,适应性强IPSOM:在后期有助于跳出局部最优HPSO:初期收敛快,但精细搜索能力较弱从收敛曲线可以观察到:
最快的收敛速度中后期仍能持续改进早期阶段收敛快,但后期改进不明显最为平稳,但整体效果不及其他变体APSO在Schwefel's P2.21函数优化问题上综合表现最佳自适应策略对算法性能提升显著变异操作有助于维持种群多样性混合策略能在特定阶段提供优势精度要求高的场景,建议使用APSO计算资源有限时,HPSO是较好的选择稳定性时,SPSO仍是可靠选择解空间复杂时,IPSOM的变异特性更有价值import numpy as np
import matplotlib.pyplot as plt
from tqdm import tqdm
# Schwefel's P2.21函数实现
def schwefel_p221(x):
return np.max(np.abs(x))
# 粒子类定义
class Particle:
def __init__(self, dim):
self.position = np.random.uniform(-100, 100, dim)
self.velocity = np.random.uniform(-1, 1, dim)
self.best_position = self.position.copy()
self.best_score = float('inf')
# 标准PSO实现
def spso(num_particles, dim, max_iter):
particles = [Particle(dim) for _ in range(num_particles)]
global_best_position = np.zeros(dim)
global_best_score = float('inf')
history = []
for _ in range(max_iter):
for particle in particles:
score = schwefel_p221(particle.position)
if score < particle.best_score:
particle.best_score = score
particle.best_position = particle.position.copy()
if score < global_best_score:
global_best_score = score
global_best_position = particle.position.copy()
for particle in particles:
w = 0.7
c1 = c2 = 1.5
r1, r2 = np.random.rand(2)
particle.velocity = (w * particle.velocity +
c1 * r1 * (particle.best_position - particle.position) +
c2 * r2 * (global_best_position - particle.position))
particle.position = particle.position + particle.velocity
particle.position = np.clip(particle.position, -100, 100)
history.append(global_best_score)
return global_best_position, global_best_score, history
# 自适应PSO实现
def apso(num_particles, dim, max_iter):
particles = [Particle(dim) for _ in range(num_particles)]
global_best_position = np.zeros(dim)
global_best_score = float('inf')
history = []
w_max, w_min = 0.9, 0.4
c1_init, c1_final = 2.5, 0.5
c2_init, c2_final = 0.5, 2.5
for iter in range(max_iter):
# 更新自适应参数
progress = iter / max_iter
w = w_max - (w_max - w_min) * progress
c1 = c1_init - (c1_init - c1_final) * progress
c2 = c2_init + (c2_final - c2_init) * progress
for particle in particles:
score = schwefel_p221(particle.position)
if score < particle.best_score:
particle.best_score = score
particle.best_position = particle.position.copy()
if score < global_best_score:
global_best_score = score
global_best_position = particle.position.copy()
for particle in particles:
r1, r2 = np.random.rand(2)
particle.velocity = (w * particle.velocity +
c1 * r1 * (particle.best_position - particle.position) +
c2 * r2 * (global_best_position - particle.position))
particle.position = particle.position + particle.velocity
particle.position = np.clip(particle.position, -100, 100)
history.append(global_best_score)
return global_best_position, global_best_score, history
# 带变异的改进PSO实现
def ipsom(num_particles, dim, max_iter, p_m=0.1, sigma=1.0):
particles = [Particle(dim) for _ in range(num_particles)]
global_best_position = np.zeros(dim)
global_best_score = float('inf')
history = []
for _ in range(max_iter):
for particle in particles:
score = schwefel_p221(particle.position)
if score < particle.best_score:
particle.best_score = score
particle.best_position = particle.position.copy()
if score < global_best_score:
global_best_score = score
global_best_position = particle.position.copy()
for particle in particles:
if np.random.rand() > p_m:
w = 0.7
c1 = c2 = 1.5
r1, r2 = np.random.rand(2)
particle.velocity = (w * particle.velocity +
c1 * r1 * (particle.best_position - particle.position) +
c2 * r2 * (global_best_position - particle.position))
particle.position = particle.position + particle.velocity
else:
# 高斯变异
particle.position = particle.position + np.random.normal(0, sigma, dim)
particle.position = np.clip(particle.position, -100, 100)
history.append(global_best_score)
return global_best_position, global_best_score, history
# 混合PSO实现
def hpso(num_particles, dim, max_iter, F=0.5, cr=0.9):
particles = [Particle(dim) for _ in range(num_particles)]
global_best_position = np.zeros(dim)
global_best_score = float('inf')
history = []
for _ in range(max_iter):
for particle in particles:
score = schwefel_p221(particle.position)
if score < particle.best_score:
particle.best_score = score
particle.best_position = particle.position.copy()
if score < global_best_score:
global_best_score = score
global_best_position = particle.position.copy()
for particle in particles:
w = 0.7
c1 = c2 = 1.5
r1, r2 = np.random.rand(2)
if np.random.rand() < cr:
# 差分进化策略
idx1, idx2 = np.random.randint(0, num_particles, 2)
diff_vector = F * (particles[idx1].position - particles[idx2].position)
particle.velocity = (w * particle.velocity + diff_vector +
c1 * r1 * (particle.best_position - particle.position) +
c2 * r2 * (global_best_position - particle.position))
else:
particle.velocity = (w * particle.velocity +
c1 * r1 * (particle.best_position - particle.position) +
c2 * r2 * (global_best_position - particle.position))
particle.position = particle.position + particle.velocity
particle.position = np.clip(particle.position, -100, 100)
history.append(global_best_score)
return global_best_position, global_best_score, history
def run_comparison():
# 实验参数设置
num_particles = 50
dim = 30
max_iter = 1000
num_runs = 30
# 存储结果
all_results = {
'SPSO': {'scores': [], 'histories': []},
'APSO': {'scores': [], 'histories': []},
'IPSOM': {'scores': [], 'histories': []},
'HPSO': {'scores': [], 'histories': []}
}
# 运行多次实验
for i in tqdm(range(num_runs), desc="Running experiments"):
# 运行各算法并保存结果
_, score_spso, hist_spso = spso(num_particles, dim, max_iter)
_, score_apso, hist_apso = apso(num_particles, dim, max_iter)
_, score_ipsom, hist_ipsom = ipsom(num_particles, dim, max_iter)
_, score_hpso, hist_hpso = hpso(num_particles, dim, max_iter)
all_results['SPSO']['scores'].append(score_spso)
all_results['APSO']['scores'].append(score_apso)
all_results['IPSOM']['scores'].append(score_ipsom)
all_results['HPSO']['scores'].append(score_hpso)
all_results['SPSO']['histories'].append(hist_spso)
all_results['APSO']['histories'].append(hist_apso)
all_results['IPSOM']['histories'].append(hist_ipsom)
all_results['HPSO']['histories'].append(hist_hpso)
# 统计分析
for alg in all_results:
scores = all_results[alg]['scores']
print(f"\n{alg} Statistics:")
print(f"Mean: {np.mean(scores):.2e}")
print(f"Std: {np.std(scores):.2e}")
print(f"Best: {np.min(scores):.2e}")
print(f"Worst: {np.max(scores):.2e}")
# 绘制收敛曲线
plt.figure(figsize=(10, 6))
for alg in all_results:
histories = np.array(all_results[alg]['histories'])
mean_history = np.mean(histories, axis=0)
plt.plot(mean_history, label=alg)
plt.yscale('log')
plt.xlabel('Iteration')
plt.ylabel('Best Score (log scale)')
plt.title("Convergence Curves on Schwefel's P2.21 Function")
plt.legend()
plt.grid(True)
plt.show()
if __name__ == "__main__":
run_comparison()