python实现连续型的遗传算法求解方程的局部最优解

GitHub

https://github.com/LWX1/genetic

遗传算法(Genetic Algorithm)是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法

遗传算法是一个求解问题近似解的算法,如一个很复杂且可能没有最优解,或者最优解很难求解的问题,这时就需要用到遗传算法。它是在一定的范围内求解出问题的近似解。


 思路描述

遗传算法主要分为七个步骤:

  1. 染色体编码
  2. 群体的初始化
  3. 适应值评价
  4. 选择种群(选择算子)
  5. 种群交配
  6. 种群变异
  7. 算法流程(迭代次数)

 

 

想了解更详细的遗传算法理论,参考

https://www.jianshu.com/p/ae5157c26af9

https://blog.csdn.net/qq_31805821/article/details/79763326

理论再多也始终不如实践,现在我们来实践一下

题目:

y = f(x1,x2,x3,x4)= 1/(x1^2+x2^2+x3^3+x4^4+1),其中 -5 < x1,x2,x3,x4 < 5,求解 y 的最大值。

利用遗传算法求解:

按照上述的步骤

①染色体编码和群体的初始化

1 def init():
2     x = (np.mat(np.random.rand(5, 4)))
3     x *= 10
4     x -= 5
5     print('随机生成染色体:')
6     print(x)
7     return x
View Code

②适应值评价

 1 def adapt(x):
 2     f = []
 3     for i in x:
 4         k = 0
 5         for j in i:
 6             k += pow(j, 2)
 7         k += 1
 8         k = 1 / k
 9         f.append(k)
10     return f
View Code

③选择种群(选择算子)这里选择的算子为:轮盘赌选择算法

 1 def select(f):
 2     sum = 0
 3     f1 = []
 4     for i in f:
 5         sum += i
 6     print(f)
 7     print('群体适应性的总和:')
 8     print(sum)
 9     for i in f:
10         i /= sum
11         f1.append(i)
12     print('单体适应性值与群体适应性的总和的比:')
13     print(f1)
14     return f1
15 #随机产生随机数,再与染色体适应值比,判断是否选中该染色体
16 #返回选中后的染色体
17 def select1(f, x):
18     f1 = f.copy()
19     c = np.random.rand(1,5).tolist()
20     print('每组染色体的随机数')
21     print(c)
22     C = []
23     f2 = []
24     for i in c:
25         sum = 0
26         for k,j in enumerate(i):
27             sum += f1[k]
28             f1[k] = sum     #适应值的和
29             C.append(j)
30     for i in C:
31         for j in range(len(f1)):
32             if i < f1[j]:
33                 f2.append(f1.index(f1[j]))  #得到选中染色体的坐标
34                 break;
35     x1 = x.copy()
36     for i,j in enumerate(f2):
37         x1[i] = x[j]       #得到种群
38     print('选择后得到的种群:')
39     x1 = np.around(x1, decimals = 4)
40     print(x1)
41     return x1
View Code

④种群的交配

 1 def copulation(f):
 2     f1 = []
 3     f2 = []
 4     c = np.random.rand(1, 5).tolist()
 5     print('随机产生的交配概率与0.85对比:')
 6     print(c)
 7     for i in c:
 8         for j in i:
 9             if j < 0.85:     #交配概率
10                 f1.append(i.index(j))  #交配的染色体位置
11     for i in f1:
12         f2.append(f[i])           #交配的染色体
13     print('需要交配的染色体组:')
14     print(f2)
15     print('每两组分别随机产生的交配位:')
16     for i in range(len(f1)):
17         if i % 2 != 0:
18             rand = random.randint(0,3)      #随机产生交配位
19             print(rand)
20             for k in range(rand + 1, len(f2[0])):
21                 f2[i-1][k],f2[i][k] = f2[i][k],f2[i-1][k] #交配
22     for i,j in enumerate(f1):
23         f[j] = f2[i]
24     print('交配后的种群:')
25     print(f)
26     return f
View Code

⑤种群变异

 1 def variation(f):
 2     c = np.random.rand(5, 4) #染色体生成随机数
 3     print('每组染色体的每个基因随机生成的随机数:')
 4     print(c)
 5     c = np.where(c < 0.1, -1, c)  #判断随机数小于0.1为变异
 6     print('随机数小于0.1的为变异,变异的随机数变为-1')
 7     print(c)
 8     #print(f)
 9     for n, i in enumerate(c):
10         if -1 in i:
11             for m, j in enumerate(i):
12                 if j == -1:
13                     #print('变异的位置:', n, m)
14                     f[n][m] = np.random.rand()* 10 - 5  #随机数替代变异数
15     print('变异染色体替换后:')
16     print(f)
17     return f
View Code

⑥迭代次数为1000次

运行两次的结果:

由方程y = 1/(x1^2+x2^2+x3^3+x4^4+1) -5 < x1,x2,x3,x4 < 5

可知,最优解:

当x1,x2,x3,x4 都为0 时的解为 1 为最优解。

次算法迭代1000次已经非常接近最优解了,说明此算法迭代1000次的准确性已经很高了,那假如迭代10000次,或者更长呢,是否可以得到最优解1呢

我没有迭代过,毕竟电脑有点垃圾,可能跑不起来。

总结与收获

未学遗传算法就早已听说过遗传算法,刚看到遗传算法,真的是一个头两个大,密密麻麻的文字,看着心累,幸好有老师的讲解,再加上自己的仔细阅览,终究了解了一下。

所以按照自己的了解,写下了这个算法,可能刚学,还有很多需要地方可以优化,只有在后续之中的不断学习再更改优化了。

 

 

 

 

 

 

 

 

posted @ 2019-04-07 12:50  忆回  阅读(1783)  评论(0编辑  收藏  举报