• 遗传算法python


    假设函数eq?y%3Df%28x_%7B1%7D%2Cx_%7B2%7D%2Cx_%7B3%7D%2Cx_%7B4%7D%29%3D%5Cfrac%7B1%7D%7B1+%7Cx_%7B1%7D%7C+%7Cx_%7B2%7D%7C+%7Cx_%7B3%7D%7C+%7Cx_%7B4%7D%7C%7D其中eq?-10%5Cleq%20x_%7B1%7D%2Cx_%7B2%7D%2Cx_%7B3%7D%2Cx_%7B4%7D%5Cleq%2010试用遗传算法求解y的最大值,请仿照例4.1参考课件第三章遗传算法的流程”)写出关键的求解步骤

    1. import random
    2. import math
    3. import matplotlib.pyplot as plt
    4. plt.rcParams['font.sans-serif']=['SimHei']
    5. plt.rcParams['axes.unicode_minus']=False
    6. '''产生初始种群'''
    7. def initialpopulation(NP,n,x0,x1):
    8. '''NP代表种群规模,n代表目标函数的未知量的个数;
    9. x0代表未知数取值的下限,x1代表未知数取值的上限'''
    10. initial=[]
    11. for i in range(NP):
    12. n_initial=[random.uniform(x0,x1) for j in range(n)]
    13. initial.append(n_initial)
    14. return initial
    15. '''标定适值函数'''
    16. def fitnessfunction(X):
    17. '''X代表存储各个未知量的取值的列表'''
    18. return 1/(math.sqrt(X[0]**2)+math.sqrt(X[1]**2)+math.sqrt(X[2]**2)+math.sqrt(X[3]**2)+1)
    19. '''采用轮盘赌选择算法选择个体'''
    20. def selection(NP,X0):
    21. '''NP代表种群规模,X0代表种群'''
    22. #计算种群中各个个体的适应值
    23. value=[]
    24. for i in range(NP):
    25. value.append(fitnessfunction(X0[i]))
    26. '''计算适应度和累计概率函数'''
    27. #计算选择概率
    28. fsum=0
    29. for i in range(NP):
    30. fsum=fsum+value[i]**2
    31. value_ratio=[]
    32. for i in range(NP):
    33. value_ratio.append((value[i]**2)/fsum)
    34. #计算累加概率
    35. value_ratio_add=[]
    36. for i in range(NP):
    37. if i==0:
    38. value_ratio_add.append(value_ratio[i])
    39. else:
    40. value_ratio_add.append(value_ratio_add[i-1]+value_ratio[i])
    41. #产生[0,1]之间的随机数,进行NP次轮转
    42. random_ratio=[random.uniform(0,1) for i in range(NP)]
    43. #进行轮盘赌选择
    44. choose_index=[] #从0开始计
    45. value_ratio_add0=[0,*value_ratio_add] #在列表value_ratio_add的最前面加上一个0
    46. for i in range(NP):
    47. for j in range(NP):
    48. if random_ratio[i]>=value_ratio_add0[j] and random_ratio[i]1]:
    49. choose_index.append(j)
    50. break
    51. #得到经过轮盘赌选择算法后的种群
    52. population=[X0[i] for i in choose_index]
    53. return population
    54. '''遗传运算——单切点交叉'''
    55. def crossover1(X0,pc,NP,n):
    56. '''X0代表种群,pc代表交叉概率,NP代表种群规模,n代表染色体上的基因数目'''
    57. #对每个染色体生成一个[0,1]之间的随机数
    58. random_crossover=[random.uniform(0,1) for i in range(NP)]
    59. #判断哪些染色体进行交叉运算
    60. crossover_index=[] #种群中进行交叉运算的染色体的索引值
    61. for i in range(NP):
    62. if random_crossover[i]
    63. crossover_index.append(i)
    64. #判断初步确定的需要交叉的染色体个数,如果为奇数,则最后一个染色体不进行交叉运算
    65. if (len(crossover_index)%2)!=0:
    66. crossover_index.pop()
    67. crossover_index=crossover_index
    68. #进行单切点交叉
    69. if len(crossover_index)!=0:
    70. randint_index=[random.randint(0,n-2) for i in range(int(len(crossover_index)/2))] #选择切点
    71. for i in range(0,len(crossover_index),2):
    72. crossover1=X0[crossover_index[i]]
    73. crossover2=X0[crossover_index[i+1]]
    74. crossoverindex=randint_index[int(i/2)]
    75. #分割
    76. crossover1_0=[crossover1[j] for j in range(crossoverindex+1)]
    77. crossover1_1=[crossover1[j] for j in range(crossoverindex+1,n)]
    78. crossover2_0 = [crossover2[j] for j in range(crossoverindex + 1)]
    79. crossover2_1 = [crossover2[j] for j in range(crossoverindex + 1, n)]
    80. #交换
    81. X0[crossover_index[i]]=[*crossover1_0,*crossover2_1]
    82. X0[crossover_index[i+1]]=[*crossover2_0,*crossover1_1]
    83. #返回进行单切点交叉后的种群
    84. return X0
    85. '''遗传运算——双切点交叉'''
    86. def crossover2(X0,pc,NP,n):
    87. '''X0代表种群,pc代表交叉概率,NP代表种群规模,n代表染色体上的基因数目'''
    88. # 对每个染色体生成一个[0,1]之间的随机数
    89. random_crossover=[random.uniform(0, 1) for i in range(NP)]
    90. # 判断哪些染色体进行交叉运算
    91. crossover_index=[] # 种群中进行交叉运算的染色体的索引值
    92. for i in range(NP):
    93. if random_crossover[i]
    94. crossover_index.append(i)
    95. # 判断初步确定的需要交叉的染色体个数,如果为奇数,则最后一个染色体不进行交叉运算
    96. if (len(crossover_index)%2)!=0:
    97. crossover_index.pop()
    98. crossover_index=crossover_index
    99. #进行双切点交叉
    100. if len(crossover_index)!=0:
    101. randint_index=[sorted(random.sample([i for i in range(0,n-1)],2)) for i in range(int(len(crossover_index)/2))]
    102. for i in range(0,len(crossover_index),2):
    103. crossover1=X0[crossover_index[i]]
    104. crossover2=X0[crossover_index[i+1]]
    105. crossoverindex=randint_index[int(i/2)]
    106. #分割
    107. crossover1_1=[crossover1[j] for j in range(crossoverindex[0]+1)]
    108. crossover1_2=[crossover1[j] for j in range(crossoverindex[0]+1,crossoverindex[1]+1)]
    109. crossover1_3=[crossover1[j] for j in range(crossoverindex[1]+1,n)]
    110. crossover2_1=[crossover2[j] for j in range(crossoverindex[0]+1)]
    111. crossover2_2=[crossover2[j] for j in range(crossoverindex[0]+1,crossoverindex[1]+1)]
    112. crossover2_3=[crossover2[j] for j in range(crossoverindex[1]+1,n)]
    113. #交换
    114. X0[crossover_index[i]]=[*crossover1_1,*crossover2_2,*crossover1_3]
    115. X0[crossover_index[i+1]]=[*crossover2_1,*crossover1_2,*crossover2_3]
    116. #返回进行双切点交叉后的种群
    117. return X0
    118. '''进行遗传运算——变异'''
    119. def mutation(X0,pm,NP,n,x0,x1):
    120. '''X0代表种群,pm代表交叉概率,NP代表种群规模,n代表染色体上的基因数目
    121. x0代表未知数取值的下限,x1代表未知数取值的上限'''
    122. #生成在[0,1]上的随机数列表
    123. random_gene=[[random.uniform(0,1) for i in range(n)] for j in range(NP)]
    124. #进行变异运算
    125. for i in range(NP):
    126. for j in range(n):
    127. if random_gene[i][j]
    128. X0[i][j]=random.uniform(x0,x1)
    129. #返回经过变异操作后的种群
    130. return X0
    131. '''计算种群中所有个体的适应值并返回最大值'''
    132. def fitnessmax(X0,NP):
    133. '''X0代表种群,NP代表种群规模'''
    134. #计算种群中各个个体的适应值
    135. value=[]
    136. for i in range(NP):
    137. value.append(fitnessfunction(X0[i]))
    138. value_max=max(value)
    139. #适应值最大所对应的索引值
    140. index_max=value.index(max(value))
    141. #适应值最大所对应的染色体
    142. X0_max=X0[index_max]
    143. return value_max,X0_max
    144. '''计算种群的平均适应值'''
    145. def fitness_avg(X0,NP):
    146. '''X0代表种群,NP代表种群规模'''
    147. #计算种群中各个个体的适应值
    148. value=[]
    149. for i in range(NP):
    150. value.append(fitnessfunction(X0[i]))
    151. #平均适应值
    152. value_avg=sum(value)/NP
    153. return value_avg
    154. '''使用单切点交叉的遗传算法'''
    155. def GA1(NP,NG,n,x0,x1,pc,pm):
    156. '''NP代表种群规模,NG代表最大代数,n代表一个染色体的基因数
    157. x0代表未知数取值的下限,x1代表未知数取值的上限
    158. pc代表交叉概率,pm代表变异概率'''
    159. #遗传算法——单切点交叉
    160. print("----------------------------------------------------------遗传算法(单切点交叉)----------------------------------------------------------")
    161. #产生初始种群
    162. X0=initialpopulation(NP,n,x0,x1)
    163. #存储每一代最大适应值和对应的函数值的列表
    164. fitnessmax_list=[]
    165. X0max_list=[]
    166. #历史最大适应值和对应的函数值
    167. history_max=0
    168. history=[]
    169. history_X0=[]
    170. for i in range(NG):
    171. '''得到种群的最大适应值和对应的染色体'''
    172. value_max,valueX0_max=fitnessmax(X0,NP)
    173. fitnessmax_list.append(value_max)
    174. X0max_list.append(valueX0_max)
    175. if i==0:
    176. history_max=value_max
    177. history.append(history_max)
    178. history_X0.append(valueX0_max)
    179. else:
    180. if value_max>=history_max:
    181. history_max=value_max
    182. history.append(history_max)
    183. history_X0.append(valueX0_max)
    184. else:
    185. history.append(history_max)
    186. history_X0.append(history_X0[i-1])
    187. print("第{}代:{} value_max={}".format(i + 1, history_X0[i], history[i]))
    188. '''选择'''
    189. X1=selection(NP,X0)
    190. '''双切点交叉运算'''
    191. X2=crossover1(X1,pc,NP,4)
    192. '''变异运算'''
    193. X3=mutation(X2,pm,NP,4,-10,10)
    194. X0=X3
    195. print("最优解Best={}".format(history[-1]))
    196. print("---------------------------------------------------------------进程结束---------------------------------------------------------------")
    197. '''绘制随着代数的增加每一代的最大适应值和历史最大适应值的变化'''
    198. ax1=plt.subplot(111)
    199. ax1.plot(range(1,NG+1),fitnessmax_list,c='plum',label="每一代的最大适应值")
    200. ax1.set_ylabel("适应值")
    201. ax1.set_xlabel("代数")
    202. plt.title("遗传算法(单切点交叉)每一代的最大适应值随代数的变化")
    203. ax1.legend()
    204. plt.show()
    205. ax2=plt.subplot(111)
    206. ax2.plot(range(1,NG+1),history,c='orange',label="历史最大适应值")
    207. ax2.set_ylabel("适应值")
    208. ax2.set_xlabel("代数")
    209. plt.title("遗传算法(单切点交叉)的优化过程")
    210. ax2.legend()
    211. plt.show()
    212. return fitnessmax_list[-1],history[-1],X0max_list[-1],history_X0[-1]
    213. '''使用双切点交叉的遗传算法'''
    214. def GA2(NP,NG,n,x0,x1,pc,pm):
    215. '''NP代表种群规模,NG代表最大代数,n代表一个染色体的基因数
    216. x0代表未知数取值的下限,x1代表未知数取值的上限
    217. pc代表交叉概率,pm代表变异概率'''
    218. #遗传算法——单切点交叉
    219. print("----------------------------------------------------------遗传算法(双切点交叉)----------------------------------------------------------")
    220. #产生初始种群
    221. X0=initialpopulation(NP,n,x0,x1)
    222. #存储最大适应值和对应的函数值的列表
    223. fitnessmax_list=[]
    224. X0max_list=[]
    225. #历史最大适应值
    226. history_max=0
    227. history=[]
    228. history_X0=[]
    229. for i in range(NG):
    230. '''得到种群的最大适应值和对应的染色体'''
    231. value_max,valueX0_max=fitnessmax(X0,NP)
    232. fitnessmax_list.append(value_max)
    233. X0max_list.append(valueX0_max)
    234. if i==0:
    235. history_max=value_max
    236. history.append(history_max)
    237. history_X0.append(valueX0_max)
    238. else:
    239. if value_max>=history_max:
    240. history_max=value_max
    241. history.append(history_max)
    242. history_X0.append(valueX0_max)
    243. else:
    244. history.append(history_max)
    245. history_X0.append(history_X0[i-1])
    246. print("第{}代:{} value_max={}".format(i + 1, history_X0[i], history[i]))
    247. '''选择'''
    248. X1=selection(NP,X0)
    249. '''双切点交叉运算'''
    250. X2=crossover2(X1,pc,NP,4)
    251. '''变异运算'''
    252. X3=mutation(X2,pm,NP,4,-10,10)
    253. X0=X3
    254. print("最优解Best={}".format(history[-1]))
    255. print("---------------------------------------------------------------进程结束---------------------------------------------------------------")
    256. '''绘制随着代数的增加最大适应值的变化'''
    257. ax1=plt.subplot(111)
    258. ax1.plot(range(1,NG+1),fitnessmax_list,c='plum',label="每一代的最大适应值")
    259. ax1.set_ylabel("适应值")
    260. ax1.set_xlabel("代数")
    261. plt.title("遗传算法(双切点交叉)每一代的最大适应值随代数的变化")
    262. ax1.legend()
    263. plt.show()
    264. ax2=plt.subplot(111)
    265. ax2.plot(range(1,NG+1),history,c='orange',label="历史最大适应值")
    266. ax2.set_ylabel("适应值")
    267. ax2.set_xlabel("代数")
    268. plt.title("遗传算法(双切点交叉)的优化过程")
    269. ax2.legend()
    270. plt.show()
    271. return fitnessmax_list[-1],history[-1],X0max_list[-1],history_X0[-1]
    272. '''主函数'''
    273. if __name__=="__main__":
    274. '''规定最大代数'''
    275. NG=1000
    276. '''规定种群规模'''
    277. NP=100
    278. '''规定交叉率'''
    279. pc=0.9
    280. '''规定变异率'''
    281. pm=0.1
    282. '''规定一个染色体上的基因数'''
    283. n=4
    284. '''规定未知数的下限'''
    285. x0=-10
    286. '''规定未知数的上限'''
    287. x1=10
    288. '''存储遗传算法中单切点交叉和双切点交叉最后得到的最大适应值及对应的未知数取值'''
    289. fitness_max=[]
    290. fitnessX0_max=[]
    291. '''进行单切点交叉的遗传算法'''
    292. value_max1,historymax1,valueX0_max1,historymaxX0_1=GA1(NP,NG,n,x0,x1,pc,pm)
    293. fitness_max.append(historymax1)
    294. fitnessX0_max.append(historymaxX0_1)
    295. '''进行双切点交叉的遗传运算'''
    296. value_max2,historymax2,valueX0_max2,historymaxX0_2=GA2(NP,NG,n,x0,x1,pc,pm)
    297. fitness_max.append(historymax2)
    298. fitnessX0_max.append(historymaxX0_2)
    299. print("单切点交叉的最优解:{}\t对应的未知数取值:{}\n双切点交叉的最优解:{}\t对应的未知数取值:{}".format(fitness_max[0],fitnessX0_max[0],fitness_max[1],fitnessX0_max[1]))

    第一次运行的结果:

    00f5ec8e14354437af7632dcb58c9b1d.png

    7dabe981c88c4faf8bbb529221cd3fe9.png 041e2962d9b8474f8df00772fb0670a5.png f4ac29b9ddc8473387ab0b1087b0aece.png

    6f4f42b496fa467e9fbb9d175ecc83a3.png 

    第二次运行的结果:
    c61fca1b55d24fb18f7de2b694f3d4c6.png 294be572728042188ffd87a76ac3cf5c.png

    66b36555b0764e3a99cb1f236c9523b9.png 0c0df7186d6e4689bd7740dee71dc046.png

    0ce4ee2ab02845f8aa970d24b3fd0ce8.png

     

     

  • 相关阅读:
    RabbitMQ初步到精通-第五章-RabbitMQ之消息防丢失
    初识Spring MVC
    六步快速搭建个人网站
    学点Selenium玩点新鲜~新的一年,让分布式测试有更多玩法
    前端开发之webpack
    LeetCode 面试题 16.02. 单词频率
    基于Springboot实现疫情网课管理系统项目【项目源码+论文说明】
    java基础10题
    网络爬虫之HTTP原理
    华为S5700交换机初始化和配置telnet,ssh用户方法
  • 原文地址:https://blog.csdn.net/m0_70452407/article/details/133822163