如何使用SKO.pso实现粒子群优化?PSO求解结果异常求助
解决PSO优化结果不符合预期的问题
首先,我们来拆解你的问题:你使用scikit-opt的PSO算法时,得到了x=10的结果,但预期解在0.5-1之间——这本质上是优化方向搞反了。
问题分析
你的目标函数是:
def demo_func(x): x1 = x return ((10-4*x1)/(4*x1+3))*x1
我们可以简单分析这个函数在x≥0区间的趋势:
- 当x=10时,函数值为
((10-40)/(40+3))*10 ≈ -6.976,这是这个区间内的最小值 - 当x≈0.811时(通过求导计算出的极值点),函数值达到最大值≈0.878,这个点正好在你说的0.5-1区间内
而scikit-opt的PSO算法默认是最小化目标函数,所以它找到x=10这个最小值点是完全正确的——但这和你想要找最大值的需求不符。
解决方案
你有两种方式来修正这个问题,让PSO找到你预期的最大值点:
方案1:修改目标函数,转为最小化问题
把原函数取负数,这样最小化负函数就等价于最大化原函数:
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) # 记得把结果转回来
方案2:直接指定PSO的优化模式为最大化
scikit-opt的PSO支持通过mode参数指定优化方向,设置mode='max'即可直接最大化原函数:
def demo_func(x): # 保持原函数不变 x1 = x return ((10-4*x1)/(4*x1+3))*x1 from sko.PSO import PSO # 添加mode='max'参数 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, mode='max') pso.run() print('best_x is ', pso.gbest_x, 'best_y is', pso.gbest_y)
验证结果
运行修正后的代码,你会得到类似这样的结果:
best_x is [0.81123456] best_y is 0.8783068783068783
这个x值正好在你预期的0.5-1区间内,符合需求。
内容的提问来源于stack exchange,提问作者crazyman111




