国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

遺傳算法之Python實(shí)現(xiàn)代碼

2020-01-04 16:34:38
字體:
供稿:網(wǎng)友

寫在前面

之前的文章中已經(jīng)講過了遺傳算法的基本流程,并且用MATLAB實(shí)現(xiàn)過一遍了。這一篇文章主要面對(duì)的人群是看過了我之前的文章,因此我就不再贅述遺傳算法是什么以及基本的內(nèi)容了,假設(shè)大家已經(jīng)知道我是怎么寫遺傳算法的了。

Python的遺傳算法主函數(shù)

我的思想是,創(chuàng)建一個(gè)染色體的類,其中包括了兩個(gè)變量:染色體chrom與適應(yīng)度fitness。因此我們就可以通過直接建立對(duì)象來作為種群中的個(gè)體。

#染色體的類class Chrom:  chrom = []  fitness = 0  def showChrom(self):    print(self.chrom)  def showFitness(self):    print(self.fitness)

所以我們開始設(shè)置基礎(chǔ)參數(shù)。其中種群的表達(dá)方式我用的是字典,也就是用一個(gè)字典來保存種群內(nèi)的所有個(gè)體,這個(gè)也是我想出來的創(chuàng)建多個(gè)對(duì)象的方法。

將字典的索引為個(gè)體的標(biāo)號(hào),如:chrom1, chrom2等。字典索引的值就是一個(gè)對(duì)象。這個(gè)對(duì)象擁有兩個(gè)屬性,就是染色體與適應(yīng)度。

其實(shí)在這一方便來說,我覺得在思路上是優(yōu)于利用MATLAB的矩陣式編程的。因?yàn)檫@樣可以很直觀的將個(gè)體與個(gè)體的屬性這一種思想給表達(dá)出來,相比一堆矩陣來說,在邏輯上比較容易接受。

#基礎(chǔ)參數(shù)N = 200 #種群內(nèi)個(gè)體數(shù)目mut = 0.2 #突變概率acr = 0.2 #交叉概率pop = {} #存儲(chǔ)染色體的字典for i in range(N):  pop['chrom'+str(i)] = Chrom()chromNodes = 2 #染色體節(jié)點(diǎn)數(shù)(變量個(gè)數(shù))iterNum = 10000 #迭代次數(shù)chromRange = [[0, 10], [0, 10]] #染色體范圍aveFitnessList = [] #平均適應(yīng)度bestFitnessList = [] #最優(yōu)適應(yīng)度

之后就是初始染色體了,其中就牽扯到了各種用來初始化種群、計(jì)算適應(yīng)度、找最優(yōu)等函數(shù),我在這里分出了兩個(gè)文件,分別為Genetic.py與Fitness.py。

Genetic.py里面有八個(gè)函數(shù),主要包含了作用于種群或者染色體操作的函數(shù),分別為:

  1. findBest函數(shù),用于尋找種群中的最優(yōu)染色體;
  2. findworse函數(shù),用于尋找種群中的最劣染色體;
  3. initialize函數(shù),用于初始化種群;
  4. calAveFitness函數(shù),用于計(jì)算種群的平均適應(yīng)度;
  5. mutChrom函數(shù),用于對(duì)染色體進(jìn)行變異;
  6. inRange函數(shù),用于判斷染色體節(jié)點(diǎn)值是否越界;
  7. acrChrom函數(shù),用于對(duì)染色體進(jìn)行交叉;
  8. compareChrom函數(shù),用于比較兩個(gè)染色體孰優(yōu)孰劣。

Fitness.py里面有兩個(gè)函數(shù),主要包含了對(duì)適應(yīng)度操作的函數(shù),分別為:

  1. calFitness函數(shù),用來迭代每一個(gè)個(gè)體,并計(jì)算適應(yīng)度(利用funcFitness函數(shù)計(jì)算);
  2. funcFitness函數(shù),計(jì)算單個(gè)個(gè)體的適應(yīng)度。

因此可以列出初始化代碼為

#初始染色體pop = Genetic.initialize(pop, chromNodes, chromRange)pop = Fitness.calFitness(pop) #計(jì)算適應(yīng)度bestChrom = Genetic.findBest(pop) #尋找最優(yōu)染色體bestFitnessList.append(bestChrom[1]) #將當(dāng)前最優(yōu)適應(yīng)度壓入列表中aveFitnessList.append(Genetic.calAveFitness(pop, N)) #計(jì)算并存儲(chǔ)平均適應(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)  #比較前一個(gè)時(shí)間的最優(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  #存儲(chǔ)最優(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()

最后再在最前面加上各種庫和文件就可以運(yùn)行了。

import Geneticimport Fitnessimport matplotlib.pyplot as pltimport numpy as np

感悟

可以說最主要的感悟就是染色體這一個(gè)類。其實(shí)那個(gè)Genetic.py與Fitness.py這兩個(gè)文件也可以直接包裝成類,但是這樣一來我就嫌主文件太臃腫,在其他里面再包裝成類又多此一舉,畢竟這只是一個(gè)小程序,所以我就這樣寫了。

深刻感悟到了面向?qū)ο缶幊痰膬?yōu)點(diǎn),在編程邏輯的處理上真是一種享受,只需要思考對(duì)象的屬性即可,省去了許多復(fù)雜的思考。

另一個(gè)感悟就是創(chuàng)建多個(gè)對(duì)象時(shí),利用字典的方法來創(chuàng)建對(duì)象。當(dāng)初我也是困惑怎么建立一個(gè)類似于C++中的對(duì)象數(shù)組,上網(wǎng)查找了各種方法,結(jié)果都避而不談(當(dāng)然,也可能是我搜索能力太差沒找到),所以經(jīng)過嘗試中遇到到了這種方法。

等有空我再詳細(xì)說一下這個(gè)方法吧,這一次就先到這里。

剩余的函數(shù)補(bǔ)充

首先是Genetic.py里面的八個(gè)函數(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#計(jì)算平均適應(yīng)度def calAveFitness(pop, N):  sumFitness = 0  for i in pop:    sumFitness = sumFitness + pop[i].fitness  aveFitness = sumFitness / N  return aveFitness#進(jìn)行突變def mutChrom(pop, mut, chromNodes, bestChrom, chromRange):  for i in pop:    #如果隨機(jī)數(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#檢驗(yàn)便宜范圍是否在要求范圍內(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]#進(jìn)行交叉def acrChrom(pop, acr, chromNodes):  for i in pop:    for j in pop:      if acr > random.random():        acrNode = random.randrange(0, chromNodes)        #兩個(gè)染色體節(jié)點(diǎn)進(jìn)行交換        pop[i].chrom[acrNode], pop[j].chrom[acrNode] = pop[j].chrom[acrNode], pop[i].chrom[acrNode]  return pop#進(jìn)行比較def compareChrom(nowbestChrom, bestChrom):  if bestChrom[1] > nowbestChrom[1]:    return bestChrom  else:    return nowbestChrom

然后是Fitness.py的兩個(gè)函數(shù)

import mathdef calFitness(pop):    for i in pop:    #計(jì)算每個(gè)染色體的適應(yīng)度    pop[i].fitness = funcFitness(pop[i].chrom)  return popdef funcFitness(chrom):  #適應(yīng)度函數(shù)  fitness = math.sin(chrom[0])+math.cos(chrom[1])+0.1*(chrom[0]+chrom[1])

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到python教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 林周县| 肇庆市| 台山市| 泊头市| 曲沃县| 怀远县| 南汇区| 洪洞县| 永年县| 青浦区| 麻城市| 普兰店市| 桓台县| 武汉市| 荣成市| 高淳县| 本溪| 雅江县| 昌乐县| 尖扎县| 宜都市| 天气| 遂溪县| 余江县| 沙坪坝区| 汽车| 东乌珠穆沁旗| 星子县| 吉安县| 阜新市| 庆城县| 遵义市| 桂阳县| 新安县| 铅山县| 天津市| 布尔津县| 广昌县| 辽宁省| 阜平县| 高碑店市|