遺傳演算法 python實現

2021-09-01 18:25:59 字數 3755 閱讀 7801

# encoding=utf-8

import math

import random

import operator

class ga():

def __init__(self, length, count):

# 染色體長度

self.length = length

# 種群中的染色體數量

self.count = count

# 隨機生成初始種群

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

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 gen_chromosome(self, length):

"""隨機生成長度為length的染色體,每個基因的取值是0或1

這裡用乙個bit表示乙個基因

"""chromosome = 0

for i in xrange(length):

# 終於明白了 這裡的或是整個二進位制比對的或|,比如10和1或下來的結果是11, 1001和101或的結果是1101,所以此處是個不斷隨機或出來的長度

chromosome |= (1 << i) * random.randint(0, 1) # 這裡每次左移, 隨機生成乙個0或者1的數字,這樣不斷左移生成給定長度的二進位制染色體

print ''.format(chromosome)

return chromosome

def gen_population(self, length, count):

"""獲取初始種群(乙個含有count個長度為length的染色體的列表)

"""return [self.gen_chromosome(length) for i in xrange(count)]

def fitness(self, chromosome):

"""計算適應度,將染色體解碼為0~9之間數字,代入函式計算

因為是求最大值,所以數值越大,適應度越高

"""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)] # 從小到大排序,形成新列表

# 選出適應性強的染色體

retain_length = int(len(graded) * retain_rate) # 根據比例值 找到前。個適應性強的染色體 作為下一代的父母親

parents = graded[:retain_length]

# 選出適應性不強,但是倖存的染色體 從後面中 隨機選取一比例 也放到父母親中

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:

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

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

if male != female: # 父母親序號不能相同

# 隨機選取交叉點

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

# 生成掩碼,方便位操作

mask = 0

for i in xrange(cross_pos):

mask |= (1 << i)

male = parents[male]

female = parents[female]

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

child = ((male & mask) | (female & ~mask)) & ((1 << self.length) - 1)

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

self.population = parents + children

def mutation(self, rate):

"""變異

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

"""for i in xrange(len(self.population)):

if random.random() < rate:

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

self.population[i] ^= 1 << j

def decode(self, chromosome):

"""解碼染色體,將二進位制轉化為屬於[0, 9]的實數

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

def result(self):

"""獲得當前代的最優值,這裡取的是函式取最大值時x的值。

"""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, 20)

# 200次進化迭代

for x in xrange(500):

ga.evolve()

print ga.result()

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

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

遺傳演算法python實現

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

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

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