粒子群优化算法(PSO)python实现(人工智能作业)


本文不对PSO多做解释,代码主打通俗,只是最普通的PSO。

因为作业没有要求保存每一代的position and speed并且没有要求做自适应的动态惯性因子,所以一切从简。

 

作业要求:

  粒子数:100

  迭代次数:100    // solving的参数

  xx2 x范围:[0, 15]

  求解函数:y = 2x12 - 3x22 - 4x1 + 5x2 + x3

  以图的形式体现全局最优的变化

 

  1 import math
  2 import random
  3 import matplotlib.pyplot as plt
  4 
  5 c1 = 2      # 学习因子                          # Learning coefficient
  6 c2 = 2
  7 
  8 def fitness(x1,x2,x3):                             #适应度函数                            # Fitness Function
  9     return math.floor((2*x1**2 - 3*x2**2 - 4*x1 + 5*x2 + x3)*100) / 100
 10 
 11 class PSO:
 12     def __init__(self):
 13         self.pop_size = 100                         # 粒子群个体数                         # the number of the instance in Particle swarm
 14         self.dim = 3                                # 变量数                               # the number of variables
 15         self.omega = 0.4                            # 惯性因子                             # Inertia factor
 16         self.x_max = 15
 17         self.x_min = 0
 18         self.v_max = (self.x_max - self.x_min) * 0.05
 19         self.v_min = -(self.x_max - self.x_min) * 0.05
 20         self.position = [[]]                        # 记录当前粒子位置                      # record the current position of each particle
 21         self.speed = [[]]                           # 记录当前粒子速度                      # record the moving speed
 22         self.best_value = [[]]                      # 记录全局最优                          # record the global optimal
 23         self.value = [[]]                           # 记录当前值                            # record the current fitness and position
 24     def initial(self):
 25         for i in range(self.pop_size):
 26             "第一轮初始化"
 27             "first round of initialization"
 28             x = []
 29             v = []
 30             for j in range(self.dim):
 31                 "所有math函数只为取两位小数"
 32                 "all the math.floor() are used for rounding the result up to two decimal places"
 33                 x.append(math.floor(random.uniform(self.x_min,self.x_max) * 100) / 100)
 34                 v.append(math.floor(random.uniform(self.v_min,self.v_max) * 100) / 100)
 35             self.position.append(x)
 36             self.speed.append(v)
 37             #self.value.append((fitness(x[0],x[1],x[2]))
 38             self.value.append(((fitness(x[0],x[1],x[2])),x[0],x[1],x[2]))
 39         self.value = self.value[1:]
 40         # -------------------选择取最大值/最小值-------------------#
 41         "choose to get the max or the min value"
 42         #index = self.value.index(max(self.value))
 43         index = self.value.index(min(self.value))
 44         # -------------------选择取最大值/最小值-------------------#
 45         self.best_value.append((self.value[index][0],self.position[index][0],self.position[index][1],self.position[index][2]))
 46         self.best_value = self.best_value[1:]
 47         self.position = self.position[1:]
 48         self.speed = self.speed[1:]
 49         print("the population and fitness after initialization:")
 50         print("position :",self.position)
 51         print("value:",self.value)
 52         print("best value:",self.best_value)
 53         print("------------------------split line------------------------")
 54     def solving(self,times):
 55         for i in range(times):
 56             #print(self.value)
 57             # -------------------选择取最大值/最小值-------------------#
 58             "choose to get the max or the min value"
 59             #pbest = self.value[self.value.index(max(self.value))]
 60             #gbest = self.best_value[self.best_value.index(max(self.best_value))]
 61             pbest = self.value[self.value.index(min(self.value))]
 62             gbest = self.best_value[self.best_value.index(min(self.best_value))]
 63             # -------------------选择取最大值/最小值-------------------#
 64             print("pbest:",pbest)
 65             print("gbest",gbest)
 66             for j in range(self.pop_size):
 67                 x = []
 68                 v = []
 69                 for k in range(self.dim):
 70                     v.append(math.floor((self.omega * self.speed[j][k] + c1 * random.uniform(0,1) * (pbest[1+k] - self.position[j][k]) + c2 * random.uniform(0,1) * (gbest[1+k] - self.position[j][k])) * 100) / 100 )
 71                     x.append(math.floor((self.position[j][k] + self.speed[j][k]) * 100) / 100)
 72                     "将位置和速度限制在规定范围内"
 73                     "restrict the position and the speed"
 74                     if (v[k] < self.v_min):
 75                         v[k] = self.v_min
 76                     if (v[k] > self.v_max):
 77                         v[k] = self.v_max
 78                     if(x[k] < self.x_min):
 79                         x[k] = self.x_min
 80                     if(x[k] > self.x_max):
 81                         x[k] = self.x_max
 82                 "数据更新"
 83                 "updating"
 84                 self.position[j] = x
 85                 self.speed[j] =  v
 86                 self.value[j] = (fitness(self.position[j][0],self.position[j][1],self.position[j][2]),self.position[j][0],self.position[j][1],self.position[j][2])
 87             # -------------------选择取最大值/最小值-------------------#
 88             "choose to get the max or the min value"
 89             #index = self.value.index(max(self.value))
 90             index = self.value.index(min(self.value))
 91             # -------------------选择取最大值/最小值-------------------#
 92             "获得全局最优"
 93             "get the global optimal"
 94             self.best_value.append((self.value[index][0], self.position[index][0], self.position[index][1],self.position[index][2]))
 95     def returnbest(self):
 96         return self.best_value
 97 
 98 
 99 
100 if __name__ == '__main__':
101     demo = PSO()
102     demo.initial()
103     demo.solving(100)
104     result = demo.returnbest()
105     for i in result:
106         print("value:",i[0],"x1:",i[1],"x2:",i[2],"x3:",i[3])
107     X = []
108     Y = []
109     for i in range(100):
110         X.append(i)
111         Y.append(result[i][0])
112     plt.plot(X, Y)
113     plt.show()

 

因为作业要交给日本老师看,所以打了比较详细的双语注释,这里就不对代码多做解释了。

如果要更详细地理解PSO的流程推荐这篇:https://blog.csdn.net/daaikuaichuan/article/details/81382794

本文代码流程与上面文章所讲流程基本相同。

 

博主水平一般,欢迎批评指正。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM