使用SKO.pso实现粒子群优化时结果异常,求解决方案
问题分析与解决建议
看起来你遇到的核心问题是PSO算法默认以最小化目标函数为优化方向,但你实际想要找到的是函数的最大值点,这才导致结果和预期不符。我们先拆解下你的目标函数:
原函数表达式:
def demo_func(x): return ((10-4*x)/(4*x+3))*x
计算它在区间[0,10]内的取值就能明白原因:
- 当
x=10时,函数值为((10-40)/(40+3))*10 ≈ -6.976,这是整个区间内的最小值 - 当
x在0.5~1之间时,函数值是正数(比如x=0.8时,值≈0.847),这是函数的最大值区域
所以PSO按照默认的最小化逻辑,自然会找到x=10这个最小值点,和你的预期完全相反。
两种解决方法
你可以通过以下两种简单修改,让PSO找到你想要的最大值点:
方法1:反转目标函数(最小化等价于最大化原函数)
把原函数的返回值取反,PSO最小化这个新函数的过程,就等价于最大化原函数。最后输出结果时记得再把函数值反回来:
def demo_func(x): x1 = x return -(((10-4*x1)/(4*x1+3))*x1) # 对原函数取反 from sko.PSO import PSO pso = PSO(func=demo_func, n_dim=1, pop=40, max_iter=150, lb=[0], ub=[10], w=0.8, c1=0.5, c2=0.5) pso.run() # 输出时将函数值反回原尺度 print('best_x is ', pso.gbest_x, 'best_y is', -pso.gbest_y) import matplotlib.pyplot as plt plt.plot([-y for y in pso.gbest_y_hist]) plt.show()
方法2:直接设置PSO为最大化模式
scikit-opt的PSO类自带minimize参数,默认是True(最小化),将它设为False就能直接开启最大化优化,无需修改原函数:
def demo_func(x): x1 = x return ((10-4*x1)/(4*x1+3))*x1 from sko.PSO import PSO # 添加minimize=False参数,指定最大化目标 pso = PSO(func=demo_func, n_dim=1, pop=40, max_iter=150, lb=[0], ub=[10], w=0.8, c1=0.5, c2=0.5, minimize=False) pso.run() print('best_x is ', pso.gbest_x, 'best_y is', pso.gbest_y) import matplotlib.pyplot as plt plt.plot(pso.gbest_y_hist) plt.show()
运行任意一种方法后,你都会得到落在0.5~1区间内的best_x,对应的best_y也会是原函数的最大值(约0.85左右,和理论计算的最优值一致)。
内容的提问来源于stack exchange,提问作者crazyman111
相关产品推荐
相关产品推荐

