遺傳演算法python實現

2021-08-20 20:59:29 字數 4287 閱讀 4883

(i)實現功能

求解函式  f(x) = x + 10*sin(5*x) + 7*cos(4*x)  在區間[0, 9] 的最大值;

(ii)原理

遺傳演算法(genetic algorithm)遵循『適者生存』、『優勝劣汰』的原則,是一類借鑑生物界自然選擇和自然遺傳機制的隨機化搜尋演算法。

遺傳演算法模擬乙個人工種群的進化過程,通過選擇(selection)、交叉(crossover)以及變異(mutation)等機制,在每次迭代中都保留一組候選個體,重複此過程,種群經過若干代進化後,理想情況下其適應度達到近似最優的狀態。

(iii)內容

1.   編碼 -> 創造染色體

每乙個個體的染色體都是17位長度的二進位制數,因為我將求最大值得函式的範圍[0,9]化成了90000等份。

2.   個體 -> 種群

這個數學含義就是一維的點集。

3.   適應度函式

這裡就是函式 f(x) = x + 10*sin(5*x) + 7*cos(4*x)。

4.   遺傳運算元

4.1  選擇

通過按照適應度的大小進行排序後,先保留大的個體,再隨機選擇一部分保留。

4.2 交叉

利用掩碼來實現分別獲取父母染色體的部分基因再組合和新的個體,這裡採用的是單點交叉法(隨機選擇乙個交叉點)。

4.3 變異

採用單點變異,隨機地對某個個體的基因進行突變。

這裡的基因都是二進位制數的乙個二進位制位。

(iv)演算法實現

#求解函式 f(x) = x + 10*sin(5*x) + 7*cos(4*x) 在區間[0,9]的最大值。

import math

import random

class ga():

#initalise

def __init__(self, length, count):

#length of chromosome

self.length = length

#number of chromosome

self.count = count

# randomly get initial population

self.population = self.get_population(length, count)

def get_population(self, length, count):

# get a list of count numbers chromosome (length : length)

return [self.get_chromosome(length) for i in range(count)]

def get_chromosome(self, length):

#randomly get a chromosome which length is length

# a bit ( 0, 1 ) represent a gene

chromosome = 0

for i in range(length):

chromosome |= ( 1 << i ) * random.randint(0, 1)

return chromosome

def evolve(self, retain_rate = 0.2, random_select_rate = 0.5, mutation_rate = 0.01 ):

parents = self.selection(retain_rate, random_select_rate)

self.crossover(parents)

self.mutation(mutation_rate)

def fitness(self, chromosome):

# decode and compute fitness function

x = self.decode(chromosome)

return x + 10 * math.sin(5 * x) + 7 * math.cos(4 * x)

def selection(self, retain_rate, random_select_rate):

#英語不好表達了,我就用漢語了

#通過適應度大小從大到小進行排序,最後生成的仍然是二進位制的列表

graded = [(self.fitness(chromosome), chromosome) for chromosome in self.population]

graded = [x[1] for x in sorted(graded, reverse=true)]

# 選出適應性強的染色體,挑選20%作為父類

retain_length = int(len(graded) * retain_rate)

parents = graded[:retain_length]

# 從剩餘的80%裡面選出適應性不強,但是倖存的染色體(概率0.5)

for chromosome in graded[retain_length:]:

if random.random() < random_select_rate:

return parents

def crossover(self, parents):

#交叉產生後代

# 新出生的孩子,最終會被加入存活下來的父母之中,形成新一代的種群。

children =

#需要繁殖的數量

target_count = len(self.population) - len(parents)

while len(children) < target_count:

malelocation = random.randint(0, len(parents) - 1)

femalelocation = random.randint(0, len(parents) - 1)

male = parents[malelocation]

female = parents[femalelocation]

if malelocation != femalelocation:

#隨機選擇交叉點

cross_pos = random.randint(0, self.length)

#生成掩碼,方便位運算

mask = 0

for i in range(cross_pos):

mask |= (1 << i )

#孩子將獲得父親在交叉點前的基因和母親在交叉點後(包括交叉點)的基因

child = (male & mask) | (female & ~mask)

#經過繁殖後,孩子和父母的數量與原始種群數量相等,在這裡可以更新種群。

self.population = parents + children

def mutation(self, rate):

#對種群中的所有個體,隨機改變某個個體中的某個基因

for i in range(len(self.population)):

if random.random() < rate:

j = random.randint(0, self.length-1)

self.population[i] ^= 1 << j #^是異或運算

def decode(self, chromosome):

#將二進位制還原成十進位制

return chromosome * 9.0 / (2**self.length-1)

def result(self):

#獲得當前最優的個體值

graded = [(self.fitness(chromosome), chromosome) for chromosome in self.population]

graded = [ x[1] for x in sorted(graded, reverse = true)]

return ga.decode(graded[0])

if __name__ == '__main__':

#染色體長度為17,群落數量是300

ga = ga(17, 300)

for x in range(200):

ga.evolve()

print(ga.result())

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

關於遺傳演算法 遺傳演算法是仿照自然界中生物進化而產生的一類優化演算法。個人感覺遺傳演算法簡單粗暴,適應性廣。關於遺傳演算法的介紹網上有很多了,這裡按照我自己的理解簡單概括一下。編碼解碼,將待優化的引數編碼為dna序列,最簡單直接的為二進位制編碼 即有兩種鹼基的dna鏈 生成隨機初代 選擇,適應度 ...

遺傳演算法 python實現

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

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

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