如何调整Python中的if条件以限制变量在0-12区间内?
解决PSO算法粒子越界问题
问题根源
原代码仅当粒子新位置yy严格处于(x_min, x_max)区间内时才更新位置,若yy超出边界,粒子位置保持不变,但速度仍会持续累积计算,导致后续迭代中粒子极易再次越界甚至偏离可行域更远。
修正方案
当粒子新位置越界时,直接将其强制拉回可行域边界(≤x_min时设为x_min,≥x_max时设为x_max),同时重置该粒子的速度为0,避免速度持续向边界外累积,从根源上阻止粒子跳出指定范围。
修改后的关键代码段
替换原代码中位置更新的if逻辑:
# 原位置更新逻辑 if yy[i[0]] > x_min and yy[i[0]] < x_max: xx[i[0]]=yy[i[0]] # 替换为修正后的边界处理逻辑 if yy[i[0]] < x_min: xx[i[0]] = x_min v[i[0]] = 0 # 重置速度,避免继续向负方向移动 elif yy[i[0]] > x_max: xx[i[0]] = x_max v[i[0]] = 0 # 重置速度,避免继续向正方向移动 else: xx[i[0]] = yy[i[0]]
完整修正代码
import math import random import matplotlib.pyplot as plt import numpy as np def func(x): return -(1.4 - 3 * x) * math.sin(18 * x) n_par = 20 max_iter = 10 w = 0.5 c1 = 1 c2 = 2 x_min = 0 x_max = 12 xx = [] xxb = [] v=[] for i in range(n_par): xx.append(x_min + (x_max - x_min) * random.random()) v.append(random.random()) xxb = xx.copy() # 改为复制列表,避免引用赋值导致同步修改 yy=xx.copy() F = [] for i in range(n_par): F.append(func(xx[i])) ind = np.argsort(F) xxg=xx[ind[0]] dom=[] ran=[] for i in range(max_iter): dom.append(1) ran.append(1) for itr in range(max_iter): for i in enumerate(list(range(n_par))): v[i[0]]=w*v[i[0]]+c1*random.random()*(xxg-xx[i[0]])+c2*random.random()*(xxb[i[0]]-xx[i[0]]) yy[i[0]]=xx[i[0]]+v[i[0]] # 修正后的边界处理 if yy[i[0]] < x_min: xx[i[0]] = x_min v[i[0]] = 0 elif yy[i[0]] > x_max: xx[i[0]] = x_max v[i[0]] = 0 else: xx[i[0]] = yy[i[0]] # 批量更新适应度后再排序,减少重复计算 for ii in enumerate(list(range(n_par))): F[ii[0]]=func(xx[ii[0]]) ind = np.argsort(F) if func(xx[ind[0]]) < func(xxg): xxg=xx[ind[0]] for iii in enumerate(list(range(n_par))): if func(xx[iii[0]]) < func(xxb[iii[0]]): xxb[iii[0]]=xx[iii[0]] dom[itr]=itr ran[itr]=func(xxg) print(xxg) print(func(xxg))
额外优化说明
- 原代码中
xxb = xx和yy=xx是引用赋值,会导致三个变量指向同一列表,修改xx时xxb和yy会同步变化,改为xx.copy()避免该问题。 - 将
np.argsort(F)移到粒子适应度更新的外层循环,避免在每个粒子的循环中重复排序,提升代码运行效率。
内容的提问来源于stack exchange,提问作者Peter Ngnot
相关产品推荐
相关产品推荐

