python遺傳演算法 Python 遺傳演算法實現

2021-10-11 02:19:00 字數 3809 閱讀 7309

關於遺傳演算法

遺傳演算法是仿照自然界中生物進化而產生的一類優化演算法。個人感覺遺傳演算法簡單粗暴,適應性廣。關於遺傳演算法的介紹網上有很多了,這裡按照我自己的理解簡單概括一下。

編碼解碼,將待優化的引數編碼為dna序列,最簡單直接的為二進位制編碼(即有兩種鹼基的dna鏈);

生成隨機初代

選擇,適應度(由待優化的模型得到)較好的個體有更大的概率被選擇,應用比較多的方法有輪盤賭和錦標賽;

按照一定概率進行隨機的交叉變異

goto step 2

經過多個世代的迭代之後,將會收斂到最優解。交叉和編譯的作用是產生新個體,避免陷入區域性最優解。

利用python實現

前輩們常說一句話「避免重複造輪子」,其實最直接的還是搜一下別人寫的包。這裡之所以花時間自己搞乙個主要是因為這個演算法比較簡單,邏輯性很明確,比較適合練手,因此才決定自己實現一下,算是敲開python大門的第乙個專案。

編碼解碼

這裡選擇使用二進位制編碼的方式來實現,根據使用者輸入的引數範圍和精度計算出每個引數需要的位數,然後將引數空間均分對映為二進位制編碼。

copy

# encode parameters into dna

def encode(self, parameters):

dna = ''

for i in range(self.ngenes):

genesequencedigit = (parameters[i]-self.parametersrange[i,0])/(self.parametersrange[i,1]-self.parametersrange[i,0])*(2**self.genelength[i]-1)

genesequencedigit = int(round(genesequencedigit))

genesequencebin = self.int2bin(genesequencedigit, self.genelength[i])

dna = dna + genesequencebin

dna = list(dna) # trun string to list

return dna

# decode dna to parameters

def decode(self, dna):

dna = ''.join(dna) # trun list to string

parameters =

for i in range(self.ngenes):

genesequencebin = dna[self.dnaidx[i,0]:self.dnaidx[i,1]+1]

genesequencedigit = self.bin2int(genesequencebin)

parameteri = genesequencedigit/(2**self.genelength[i]-1)*(self.parametersrange[i,1]-self.parametersrange[i,0])+self.parametersrange[i,0]

return parameters

# returns the binary string of integer n, using count number of digits

def int2bin(self, n, count=32):

binstr = "".join([str((n >> y) & 1) for y in range(count-1, -1, -1)])

return binstr

# returns digit integer of binary string

def bin2int(self, n):

ret = int(n,2)

return ret

這種方式實現的精度並不是確切的為使用者輸入的精度,而是要高於使用者的輸入精度。

選擇選擇的策略使用了名為錦標賽的方式,同時新增了精英保留機制。錦標賽是指隨機選擇n個(通常n=2)候選個體,再從中選擇最優的個體進入下一代,重複多次,直到子代規模達到要求。精英保留機制是是指保護已經產生的最優個體不被淘汰,不被交叉和變異破壞。

copy

# select individuals

def select(self):

ncandidates = 2

generation =

for i in range(self.popgeneration):

candidates = random.choices(self.generation, k=ncandidates)

fitnesslist = self.fitness(candidates=candidates)

bestfitness = max(fitnesslist)

idx = fitnesslist.index(bestfitness)

self.generation = generation

return

# elitist preservation

def elitistpreservation(self):

bestfitness = max(self.fitnesslist)

if bestfitness > self.bestfitness:

idx = self.fitnesslist.index(bestfitness)

self.bestfitness = bestfitness

self.bestindividual = self.generation[idx].copy()

else:

worstindividual = min(self.fitnesslist)

idx = self.fitnesslist.index(worstindividual)

self.generation[idx] = self.bestindividual.copy()

self.fitnesslist[idx] = self.bestfitness

return

交叉和變異

交叉和編譯比較簡單,利用隨機數的方式來控制發生的概率。這裡值得一提的是,現實中可能會發生多點的變異或者交叉,只不過概率非常低,在遺傳演算法的實現中如果僅僅採用單點的交叉和變異也是可以的。

**和例子

使用例程:

copy

import geneticalgorithm as ga # 匯入geneticalgorithm模組

import math

# 根據具體的優化目標設計適應度函式,par為輸入引數的列表,ret為適應度

def fitness(par):

x = par[0]

ret = x*math.sin(10*math.pi*x)+2

return ret

maxgen = 500 # 迭代次數

popgeneration = 50 # 每個世代的個體數目

pcross = 0.1 # 發生交叉的概率

pmutation = 0.05 # 發生變異的概率

ngenes = 1 # 待優化的引數的個數

parametersrange = [[-1, 2, 0.01]] # 待優化引數的範圍及要求的精度,多個引數寫法:[[-1, 2, 0.01],[-2, 3, 0.1]]

# 建立ga物件

ga = ga.geneticalgorithm(maxgen, popgeneration, pcross, pmutation, ngenes, parametersrange, fitness)

# 顯示物件資訊

ga.info()

# 執行優化

ga.run()

# 顯示最優解

ga.result()

遺傳演算法 python 簡書 遺傳演算法

優化的演算法有很多種,從最基本的梯度下降法到現在的一些啟發式演算法,如遺傳演算法 ga 差分演化演算法 de 粒子群演算法 pso 和人工蜂群演算法 abc 舉乙個例子,遺傳演算法和梯度下降 梯度下降和遺傳演算法都是優化演算法,而梯度下降只是其中最基礎的那乙個,它依靠梯度與方向導數的關係計算出最優值...

遺傳演算法python實現

i 實現功能 求解函式 f x x 10 sin 5 x 7 cos 4 x 在區間 0,9 的最大值 ii 原理 遺傳演算法 genetic algorithm 遵循 適者生存 優勝劣汰 的原則,是一類借鑑生物界自然選擇和自然遺傳機制的隨機化搜尋演算法。遺傳演算法模擬乙個人工種群的進化過程,通過選...

遺傳演算法 python實現

encoding utf 8 import math import random import operator class ga def init self,length,count 染色體長度 self.length length 種群中的染色體數量 self.count count 隨機生成初...