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呢

我沒有迭代過,畢竟電腦有點垃圾,可能跑不起來。

總結與收獲

未學遺傳算法就早已聽說過遺傳算法,剛看到遺傳算法,真的是一個頭兩個大,密密麻麻的文字,看着心累,幸好有老師的講解,再加上自己的仔細閱覽,終究了解了一下。

所以按照自己的了解,寫下了這個算法,可能剛學,還有很多需要地方可以優化,只有在后續之中的不斷學習再更改優化了。

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM