遺傳算法之Python實現(xiàn)代碼
寫在前面
之前的文章中已經(jīng)講過了遺傳算法的基本流程,并且用MATLAB實現(xiàn)過一遍了。這一篇文章主要面對的人群是看過了我之前的文章,因此我就不再贅述遺傳算法是什么以及基本的內(nèi)容了,假設(shè)大家已經(jīng)知道我是怎么寫遺傳算法的了。
Python的遺傳算法主函數(shù)
我的思想是,創(chuàng)建一個染色體的類,其中包括了兩個變量:染色體chrom與適應(yīng)度fitness。因此我們就可以通過直接建立對象來作為種群中的個體。
#染色體的類 class Chrom: chrom = [] fitness = 0 def showChrom(self): print(self.chrom) def showFitness(self): print(self.fitness)
所以我們開始設(shè)置基礎(chǔ)參數(shù)。其中種群的表達方式我用的是字典,也就是用一個字典來保存種群內(nèi)的所有個體,這個也是我想出來的創(chuàng)建多個對象的方法。
將字典的索引為個體的標號,如:chrom1, chrom2等。字典索引的值就是一個對象。這個對象擁有兩個屬性,就是染色體與適應(yīng)度。
其實在這一方便來說,我覺得在思路上是優(yōu)于利用MATLAB的矩陣式編程的。因為這樣可以很直觀的將個體與個體的屬性這一種思想給表達出來,相比一堆矩陣來說,在邏輯上比較容易接受。
#基礎(chǔ)參數(shù) N = 200 #種群內(nèi)個體數(shù)目 mut = 0.2 #突變概率 acr = 0.2 #交叉概率 pop = {} #存儲染色體的字典 for i in range(N): pop['chrom'+str(i)] = Chrom() chromNodes = 2 #染色體節(jié)點數(shù)(變量個數(shù)) iterNum = 10000 #迭代次數(shù) chromRange = [[0, 10], [0, 10]] #染色體范圍 aveFitnessList = [] #平均適應(yīng)度 bestFitnessList = [] #最優(yōu)適應(yīng)度
之后就是初始染色體了,其中就牽扯到了各種用來初始化種群、計算適應(yīng)度、找最優(yōu)等函數(shù),我在這里分出了兩個文件,分別為Genetic.py與Fitness.py。
Genetic.py里面有八個函數(shù),主要包含了作用于種群或者染色體操作的函數(shù),分別為:
- findBest函數(shù),用于尋找種群中的最優(yōu)染色體;
- findworse函數(shù),用于尋找種群中的最劣染色體;
- initialize函數(shù),用于初始化種群;
- calAveFitness函數(shù),用于計算種群的平均適應(yīng)度;
- mutChrom函數(shù),用于對染色體進行變異;
- inRange函數(shù),用于判斷染色體節(jié)點值是否越界;
- acrChrom函數(shù),用于對染色體進行交叉;
- compareChrom函數(shù),用于比較兩個染色體孰優(yōu)孰劣。
Fitness.py里面有兩個函數(shù),主要包含了對適應(yīng)度操作的函數(shù),分別為:
- calFitness函數(shù),用來迭代每一個個體,并計算適應(yīng)度(利用funcFitness函數(shù)計算);
- funcFitness函數(shù),計算單個個體的適應(yīng)度。
因此可以列出初始化代碼為
#初始染色體 pop = Genetic.initialize(pop, chromNodes, chromRange) pop = Fitness.calFitness(pop) #計算適應(yīng)度 bestChrom = Genetic.findBest(pop) #尋找最優(yōu)染色體 bestFitnessList.append(bestChrom[1]) #將當前最優(yōu)適應(yīng)度壓入列表中 aveFitnessList.append(Genetic.calAveFitness(pop, N)) #計算并存儲平均適應(yīng)度
迭代過程的思路和邏輯與MATLAB無異
#開始迭代 for t in range(iterNum): #染色體突變 pop = Genetic.mutChrom(pop, mut, chromNodes, bestChrom, chromRange) #染色體交換 pop = Genetic.acrChrom(pop, acr, chromNodes) #尋找最優(yōu) nowBestChrom = Genetic.findBest(pop) #比較前一個時間的最優(yōu)和現(xiàn)在的最優(yōu) bestChrom = Genetic.compareChrom(nowBestChrom, bestChrom) #尋找與替換最劣 worseChrom = Genetic.findWorse(pop) pop[worseChrom[0]].chrom = pop[bestChrom[0]].chrom.copy() pop[worseChrom[0]].fitness = pop[bestChrom[0]].fitness #存儲最優(yōu)與平均 bestFitnessList.append(bestChrom[1]) aveFitnessList.append(Genetic.calAveFitness(pop, N))
最后再做一下迭代的的圖像
plt.figure(1) plt.plot(x, aveFitnessList) plt.plot(x, bestFitnessList) plt.show()
最后再在最前面加上各種庫和文件就可以運行了。
import Genetic import Fitness import matplotlib.pyplot as plt import numpy as np
感悟
可以說最主要的感悟就是染色體這一個類。其實那個Genetic.py與Fitness.py這兩個文件也可以直接包裝成類,但是這樣一來我就嫌主文件太臃腫,在其他里面再包裝成類又多此一舉,畢竟這只是一個小程序,所以我就這樣寫了。
深刻感悟到了面向?qū)ο缶幊痰膬?yōu)點,在編程邏輯的處理上真是一種享受,只需要思考對象的屬性即可,省去了許多復(fù)雜的思考。
另一個感悟就是創(chuàng)建多個對象時,利用字典的方法來創(chuàng)建對象。當初我也是困惑怎么建立一個類似于C++中的對象數(shù)組,上網(wǎng)查找了各種方法,結(jié)果都避而不談(當然,也可能是我搜索能力太差沒找到),所以經(jīng)過嘗試中遇到到了這種方法。
等有空我再詳細說一下這個方法吧,這一次就先到這里。
剩余的函數(shù)補充
首先是Genetic.py里面的八個函數(shù)
import random #尋找最優(yōu)染色體 def findBest(pop): best = ['1', 0.0000001] for i in pop: if best[1] < pop[i].fitness: best = [i, pop[i].fitness] return best #尋找最劣染色體 def findWorse(pop): worse = ['1', 999999] for i in pop: if worse[1] > pop[i].fitness: worse = [i, pop[i].fitness] return worse #賦初始值 def initialize(pop, chromNodes, chromRange): for i in pop: chromList = [] for j in range(chromNodes): chromList.append(random.uniform(chromRange[j][0], chromRange[j][1]+1)) pop[i].chrom = chromList.copy() return pop #計算平均適應(yīng)度 def calAveFitness(pop, N): sumFitness = 0 for i in pop: sumFitness = sumFitness + pop[i].fitness aveFitness = sumFitness / N return aveFitness #進行突變 def mutChrom(pop, mut, chromNodes, bestChrom, chromRange): for i in pop: #如果隨機數(shù)小于變異概率(即可以變異) if mut > random.random(): mutNode = random.randrange(0,chromNodes) mutRange = random.random() * (1-pop[i].fitness/bestChrom[1])**2 pop[i].chrom[mutNode] = pop[i].chrom[mutNode] * (1+mutRange) #判斷變異后的范圍是否在要求范圍內(nèi) pop[i].chrom[mutNode] = inRange(pop[i].chrom[mutNode], chromRange[mutNode]) return pop #檢驗便宜范圍是否在要求范圍內(nèi) def inRange(mutNode, chromRange): if chromRange[0] < mutNode < chromRange[1]: return mutNode elif mutNode-chromRange[0] > mutNode-chromRange[1]: return chromRange[1] else: return chromRange[0] #進行交叉 def acrChrom(pop, acr, chromNodes): for i in pop: for j in pop: if acr > random.random(): acrNode = random.randrange(0, chromNodes) #兩個染色體節(jié)點進行交換 pop[i].chrom[acrNode], pop[j].chrom[acrNode] = pop[j].chrom[acrNode], pop[i].chrom[acrNode] return pop #進行比較 def compareChrom(nowbestChrom, bestChrom): if bestChrom[1] > nowbestChrom[1]: return bestChrom else: return nowbestChrom
然后是Fitness.py的兩個函數(shù)
import math def calFitness(pop): for i in pop: #計算每個染色體的適應(yīng)度 pop[i].fitness = funcFitness(pop[i].chrom) return pop def funcFitness(chrom): #適應(yīng)度函數(shù) fitness = math.sin(chrom[0])+math.cos(chrom[1])+0.1*(chrom[0]+chrom[1])
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
macbook安裝環(huán)境chatglm2-6b的詳細過程
這篇文章主要介紹了macbook安裝chatglm2-6b的過程詳解,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-07-07tensorflow安裝成功import tensorflow 出現(xiàn)問題
這篇文章主要介紹了tensorflow安裝成功import tensorflow 出現(xiàn)問題,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04Gradio機器學(xué)習(xí)模型快速部署工具quickstart前篇
這篇文章主要為大家介紹了Gradio機器學(xué)習(xí)模型快速部署工具quickstart準備原文翻譯,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-04-04Python基于Faker假數(shù)據(jù)構(gòu)造庫
這篇文章主要介紹了Python基于Faker假數(shù)據(jù)構(gòu)造庫,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-11-11Python Django實現(xiàn)個人博客系統(tǒng)的搭建
個人博客是一個非常好的平臺,可以讓人們分享自己的知識和經(jīng)驗,也可以讓人們交流和互動。在這篇文章中,我們將介紹如何使用Python Django框架來開發(fā)一個個人博客系統(tǒng),希望對大家有所幫助2023-04-04