Python中的遺傳演算法工具箱:Deap
CSDN系列文章傳送門:
- 本篇文章的原文
- Deap:粒子群演算法講解
- 遺傳演算法解決背包問題的例子
- 數學建模2017國賽實例
Overview 程序概覽
官方文檔:[DEAP documentation](DEAP documentation)
1. Types : 選擇你要解決的問題類型,確定要求解的問題個數,最大值還是最小值
2. Initialization : 初始化基因編碼位數,初始值,等基本信息
3. Operators : 操作,設計evaluate函數,在工具箱中註冊參數信息:交叉,變異,保留個體,評價函數
4. Algorithm : 設計main函數,確定參數並運行得到結果
Types
from deap import base, creatorcreator.create("FitnessMin", base.Fitness, weights=(-1.0,)) # weights 1.0, 求最大值,-1.0 求最小值# (1.0,-1.0,)求第一個參數的最大值,求第二個參數的最小值creator.create("Individual", list, fitness=creator.FitnessMin)
Initialization
import randomfrom deap import toolsIND_SIZE = 10 # 種群數toolbox = base.Toolbox()toolbox.register("attribute", random.random)# 調用randon.random為每一個基因編碼編碼創建 隨機初始值 也就是範圍[0,1]toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attribute, n=IND_SIZE)toolbox.register("population", tools.initRepeat, list, toolbox.individual)
Operators
# Operators# difine evaluate function# Note that a comma is a mustdef evaluate(individual): return sum(individual),# use tools in deap to creat our applicationtoolbox.register("mate", tools.cxTwoPoint) # mate:交叉toolbox.register("mutate", tools.mutGaussian, mu=0, sigma=1, indpb=0.1) # mutate : 變異toolbox.register("select", tools.selTournament, tournsize=3) # select : 選擇保留的最佳個體toolbox.register("evaluate", evaluate) # commit our evaluate
高斯變異:
這種變異的方法就是,產生一個服從高斯分布的隨機數,取代原先基因中的實數數值。這個演算法產生的隨機數,數學期望當為當前基因的實數數值。
一個模擬產生的演算法是,產生6個服從U(0,1)的隨機數,以他們的數學期望作為高斯分布隨機數的近似。mutate方法
- 這個函數適用於輸入個體的平均值和標準差的高斯突變
- mu:python中基於平均值的高斯變異
- sigma:python中基於標準差的高斯變異
- indpb:每個屬性的獨立變異概率
mate : 交叉
select : 選擇保留的最佳個體
evaluate : 選擇評價函數,要注意返回值的地方最後面要多加一個逗號
Algorithms 計算程序
也就是設計主程序的地方,按照官網給的模式,我們要早此處設計其他參數,並設計迭代和取值的代碼部分,並返回我們所需要的值.
# Algorithmsdef main(): # create an initial population of 300 individuals (where # each individual is a list of integers) pop = toolbox.population(n=50) CXPB, MUTPB, NGEN = 0.5, 0.2, 40 # CXPB is the probability with which two individuals # are crossed # # MUTPB is the probability for mutating an individual # # NGEN is the number of generations for which the # evolution runs # Evaluate the entire population fitnesses = map(toolbox.evaluate, pop) for ind, fit in zip(pop, fitnesses): ind.fitness.values = fit print(" Evaluated %i individuals" % len(pop)) # 這時候,pop的長度還是300呢 print("-- Iterative %i times --" % NGEN) for g in range(NGEN): if g % 10 == 0: print("-- Generation %i --" % g) # Select the next generation individuals offspring = toolbox.select(pop, len(pop)) # Clone the selected individuals offspring = list(map(toolbox.clone, offspring)) # Change map to list,The documentation on the official website is wrong # Apply crossover and mutation on the offspring for child1, child2 in zip(offspring[::2], offspring[1::2]): if random.random() < CXPB: toolbox.mate(child1, child2) del child1.fitness.values del child2.fitness.values for mutant in offspring: if random.random() < MUTPB: toolbox.mutate(mutant) del mutant.fitness.values # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit # The population is entirely replaced by the offspring pop[:] = offspring print("-- End of (successful) evolution --") best_ind = tools.selBest(pop, 1)[0] return best_ind, best_ind.fitness.values # return the result:Last individual,The Return of Evaluate function
要注意的地方就是,官網中給出的Overview代碼中有一行代碼是錯誤的,需要把一個數據類型(map)轉換為list.
輸出結果
Evaluated 50 individuals-- Iterative 40 times ---- Generation 0 ---- Generation 10 ---- Generation 20 ---- Generation 30 ---- End of (successful) evolution --best_ind [-2.402824207878805, -1.5920248739487302, -4.397332290574777, -0.7564815676249151, -3.3478264358788814, -5.900475519316307, -7.739284213710048, -4.469259215914226, 0.35793917907272843, -2.8594709616875256]best_ind.fitness.values (-33.10704010746149,)
- best_ind : 最佳個體
- best_ind.fitness.values : 最佳個體在經過evaluate之後的輸出
#!usr/bin/env python# -*- coding:utf-8 _*-"""@author:fonttian @file: Overview.py@time: 2017/10/15 """# Typesfrom deap import base, creatorcreator.create("FitnessMin", base.Fitness, weights=(-1.0,))# weights 1.0, 求最大值,-1.0 求最小值# (1.0,-1.0,)求第一個參數的最大值,求第二個參數的最小值creator.create("Individual", list, fitness=creator.FitnessMin)# Initializationimport randomfrom deap import toolsIND_SIZE = 10 # 種群數toolbox = base.Toolbox()toolbox.register("attribute", random.random)# 調用randon.random為每一個基因編碼編碼創建 隨機初始值 也就是範圍[0,1]toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attribute, n=IND_SIZE)toolbox.register("population", tools.initRepeat, list, toolbox.individual)# Operators# difine evaluate function# Note that a comma is a mustdef evaluate(individual): return sum(individual),# use tools in deap to creat our applicationtoolbox.register("mate", tools.cxTwoPoint) # mate:交叉toolbox.register("mutate", tools.mutGaussian, mu=0, sigma=1, indpb=0.1) # mutate : 變異toolbox.register("select", tools.selTournament, tournsize=3) # select : 選擇保留的最佳個體toolbox.register("evaluate", evaluate) # commit our evaluate# Algorithmsdef main(): # create an initial population of 300 individuals (where # each individual is a list of integers) pop = toolbox.population(n=50) CXPB, MUTPB, NGEN = 0.5, 0.2, 40 # CXPB is the probability with which two individuals # are crossed # # MUTPB is the probability for mutating an individual # # NGEN is the number of generations for which the # evolution runs # Evaluate the entire population fitnesses = map(toolbox.evaluate, pop) for ind, fit in zip(pop, fitnesses): ind.fitness.values = fit print(" Evaluated %i individuals" % len(pop)) # 這時候,pop的長度還是300呢 print("-- Iterative %i times --" % NGEN) for g in range(NGEN): if g % 10 == 0: print("-- Generation %i --" % g) # Select the next generation individuals offspring = toolbox.select(pop, len(pop)) # Clone the selected individuals offspring = list(map(toolbox.clone, offspring)) # Change map to list,The documentation on the official website is wrong # Apply crossover and mutation on the offspring for child1, child2 in zip(offspring[::2], offspring[1::2]): if random.random() < CXPB: toolbox.mate(child1, child2) del child1.fitness.values del child2.fitness.values for mutant in offspring: if random.random() < MUTPB: toolbox.mutate(mutant) del mutant.fitness.values # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] fitnesses = map(toolbox.evaluate, invalid_ind) for ind, fit in zip(invalid_ind, fitnesses): ind.fitness.values = fit # The population is entirely replaced by the offspring pop[:] = offspring print("-- End of (successful) evolution --") best_ind = tools.selBest(pop, 1)[0] return best_ind, best_ind.fitness.values # return the result:Last individual,The Return of Evaluate functionif __name__ == "__main__": # t1 = time.clock() best_ind, best_ind.fitness.values = main() # print(pop, best_ind, best_ind.fitness.values) # print("pop",pop) print("best_ind",best_ind) print("best_ind.fitness.values",best_ind.fitness.values) # t2 = time.clock() # print(t2-t1)
推薦閱讀: