文章目录

  • 一.前言
  • 二.配词问题
    • 1.问题描述
    • 2.评价方式一 - ASCII码差异
    • 2.评价方式二 -- 与原文相同的字符个数
    • 小结

一.前言

在非线性函数寻优中,我们看到了编码方式对问题求解的重要性,但是遗传算法的评价函数的设定也对求解有至关重要的作用。如果设定的评价函数不好,可能导致算法无法正确收敛。

二.配词问题

1.问题描述

配词问题(word matching problem)是给定某字符串,以生成同样字符串为目的的问题。

例如对目标短语’to be or not to be’,要求用遗传算法生成该短语。

这里最简单直接的个体编码方式是采用13个ASCII码进行编码(当然用字符编码也是可以的,这里因为探讨的主要问题在于评价函数的选择,因此,不对编码方式做过多探索)。

考虑评价函数时,有两种评价思路:

  • 第一种思路:是将目标函数设定为与给定的字符串的ASCII码差异,此时,配词问题转化为一个目标函数最小化问题。
  • 第二种思路:是将目标函数设定与原文相同的字符个数,此时,配图问题转化为一个目标函数最大化问题。

2.评价方式一 - ASCII码差异

遗传算法操作:

  1. 个体编码:使用ASCII码数字编码,长度为13
  2. 评价函数:与给定的字符串的ASCII码差异的绝对值之和
  3. 育种选择:锦标赛选择
  4. 变异算法:交叉-均匀交叉,变异-乱序突变
  5. 环境选择:精英保留策略
    代码实现
#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
@author: liujie
@software: PyCharm
@file: ASCII差异.py
@time: 2020/11/28 19:36
"""
import numpy as np
import random
import matplotlib.pyplot as plt
from deap import creator,tools,base,algorithms# 定义问题
creator.create('FitnessMin',base.Fitness,weights=(-1.0,))
creator.create('Individual',list,fitness = creator.FitnessMin)# 个体编码-ASCII编码
gen_size = 13
toolbox = base.Toolbox()
# 小写字母“a”到“z”的ASCII码值分别为97到到122
toolbox.register('genASCII',random.randint,97,122)
toolbox.register('Individual',tools.initRepeat,creator.Individual,toolbox.genASCII,n = gen_size)
# 注册种群
toolbox.register('Population',tools.initRepeat,list,toolbox.Individual)# 评价函数-与给定的字符串的ASCII码差异之和
def eval(ind):target  = list('tobeornottobe')# ord返回对应ASCII字符串的ASCII数值target = [ord(item) for item in target]return np.sum(np.abs(np.array(ind) - np.array(target))),# 注册评价函数
toolbox.register('evaluate',eval)
# 注册遗传算法的操作:选择、交叉、突变
toolbox.register('select',tools.selTournament,tournsize = 2)
toolbox.register('mate',tools.cxUniform,indpb=0.5)
toolbox.register('mutate',tools.mutShuffleIndexes,indpb = 0.3)# 创建统计学对象
stats = tools.Statistics(key= lambda ind : ind.fitness.values)
stats.register('avg',np.mean)
stats.register('std',np.std)
stats.register('min',np.min)
stats.register('max',np.max)
# 创建日志对象
logbook = tools.Logbook()
logbook.header = 'gen','avg','std','min','max'# 遗传算法
pop_size =  100
N_GEN = 50
CXPB = 0.8
MUTPB = 0.2# 生成种群
pop = toolbox.Population(n = pop_size)# 评价初代种群
invalid_ind = [ind for ind in pop if not ind.fitness.valid]
fitnesses = list(map(toolbox.evaluate,invalid_ind))
for ind,fit in zip(pop,fitnesses):ind.fitness.values = fit
record = stats.compile(pop)
logbook.record(gen = 0,**record)# 遗传算法迭代
for gen in range(1+N_GEN):# 配重选择selectTour = toolbox.select(pop,pop_size)# 复制selectInd = list(map(toolbox.clone,selectTour))# selectInd = [toolbox.clone(_) for _ in selectTour]# 交叉for child1,child2 in zip(selectInd[::2],selectInd[1::2]):if random.random() < CXPB:toolbox.mate(child1,child2)del child1.fitness.valuesdel child2.fitness.values# 变异for ind in selectInd:if random.random() < MUTPB:toolbox.mutate(ind)del ind.fitness.values# 对于被改变的个体,更改其适应度invalid_ind = [ind for ind in selectInd if not ind.fitness.valid]fitnesses = list(map(toolbox.evaluate,invalid_ind))for ind,fit in zip(invalid_ind,fitnesses):ind.fitness.values = fit# 精英育种策略combinedPop = pop  + selectIndpop = tools.selBest(combinedPop,pop_size)# 将统计对象应用于poprecord = stats.compile(pop)logbook.record(gen = gen,**record)# 打印迭代过程
print(logbook)
# 输出结果
bestInd = tools.selBest(pop,1)[0]
bestFit = bestInd.fitness.values[0]
print('最优解为:',str(bestInd))
print('对应的函数最小值为:',str(bestFit))# 可视化
gen = logbook.select('gen')
min = logbook.select('min')
avg = logbook.select('avg')
plt.plot(gen,min,'b-',label = 'MIN_FITNESS')
plt.plot(gen,avg,'r-',label = 'AVG_FITNESS')
plt.xlabel('gen')
plt.plot('fit')
plt.legend(loc = 'upper right')
plt.show()

运行结果

gen  avg     std         min max
0   105.15  18.9644     52  143
0   86.53   11.1234     52  100
1   73.83   10.1154     43  87
2   63.96   7.74328     43  73
3   54.72   7.76155     24  64
4   46.73   7.13282     23  55
5   39.71   6.63369     21  48
6   32.72   5.20208     19  40
7   27.53   3.71606     19  32
8   23.44   3.0243      14  28
9   19.97   3.07394     11  24
10  16.56   2.63939     9   21
11  13.7    2.52784     5   17
12  10.89   2.61494     4   14
13  8.3     2.35584     3   11
14  5.68    1.55486     2   8
15  3.83    1.12299     1   5
16  2.71    0.919728    0   4
17  1.77    0.580603    0   3
18  1.27    0.690724    0   2
19  0.64    0.48        0   1
20  0.23    0.420833    0   1
21  0       0           0   0
22  0       0           0   0
23  0       0           0   0
24  0       0           0   0
25  0       0           0   0
26  0       0           0   0
27  0       0           0   0
...
194 0       0           0   0
195 0       0           0   0
196 0       0           0   0
197 0       0           0   0
198 0       0           0   0
199 0       0           0   0
200 0       0           0   0
最优解为: ['t', 'o', 'b', 'e', 'o', 'r', 'n', 'o', 't', 't', 'o', 'b', 'e']
对应的函数最小值为: 0.0

可视化

2.评价方式二 – 与原文相同的字符个数

遗传算法操作

  1. 个体编码:使用ASCII编码,长度为13
  2. 评价函数:与原文相同的字符个数
  3. 育种选择:锦标赛选择
  4. 变异算法:交叉-均匀交叉,变异-乱序突变
  5. 环境选择:精英保留策略

代码实现

#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
@author: liujie
@software: PyCharm
@file: ASCII差异.py
@time: 2020/11/28 19:36
"""
import numpy as np
import random
import matplotlib.pyplot as plt
from deap import creator,tools,base,algorithms# 定义问题
creator.create('FitnessMax',base.Fitness,weights=(1.0,))
creator.create('Individual',list,fitness = creator.FitnessMax)# 个体编码-ASCII编码
gen_size = 13
toolbox = base.Toolbox()
# 小写字母“a”到“z”的ASCII码值分别为97到到122
toolbox.register('genASCII',random.randint,97,122)
toolbox.register('Individual',tools.initRepeat,creator.Individual,toolbox.genASCII,n = gen_size)
# 注册种群
toolbox.register('Population',tools.initRepeat,list,toolbox.Individual)# 评价函数-生成的字符串与目标字符串相同的个数
def eval(ind):target = list('tobeornottobe')# ord返回对应ASCII字符串的ASCII数值target = [ord(item) for item in target]return np.sum(np.array(ind) == np.array(target)),# 注册评价函数
toolbox.register('evaluate',eval)
# 注册遗传算法的操作:选择、交叉、突变
toolbox.register('select',tools.selTournament,tournsize = 2)
toolbox.register('mate',tools.cxUniform,indpb=0.5)
toolbox.register('mutate',tools.mutShuffleIndexes,indpb = 0.5)# 创建统计学对象
stats = tools.Statistics(key= lambda ind : ind.fitness.values)
stats.register('avg',np.mean)
stats.register('std',np.std)
stats.register('min',np.min)
stats.register('max',np.max)
# 创建日志对象
logbook = tools.Logbook()
logbook.header = 'gen','avg','std','min','max'# 遗传算法
pop_size =  100
N_GEN = 200
CXPB = 0.8
MUTPB = 0.2# 生成种群
pop = toolbox.Population(n = pop_size)# 评价初代种群
invalid_ind = [ind for ind in pop if not ind.fitness.valid]
fitnesses = list(map(toolbox.evaluate,invalid_ind))
for ind,fit in zip(pop,fitnesses):ind.fitness.values = fit
record = stats.compile(pop)
logbook.record(gen = 0,**record)# 遗传算法迭代
for gen in range(1+N_GEN):# 配重选择selectTour = toolbox.select(pop,pop_size)# 复制selectInd = list(map(toolbox.clone,selectTour))# selectInd = [toolbox.clone(_) for _ in selectTour]# 交叉for child1,child2 in zip(selectInd[::2],selectInd[1::2]):if random.random() < CXPB:toolbox.mate(child1,child2)del child1.fitness.valuesdel child2.fitness.values# 变异for ind in selectInd:if random.random() < MUTPB:toolbox.mutate(ind)del ind.fitness.values# 对于被改变的个体,更改其适应度invalid_ind = [ind for ind in selectInd if not ind.fitness.valid]fitnesses = list(map(toolbox.evaluate,invalid_ind))for ind,fit in zip(invalid_ind,fitnesses):ind.fitness.values = fit# 精英育种策略combinedPop = pop  + selectIndpop = tools.selBest(combinedPop,pop_size)# 将统计对象应用于poprecord = stats.compile(pop)logbook.record(gen = gen,**record)# 打印迭代过程
print(logbook)
# 输出结果
bestInd = tools.selBest(pop,1)[0]
bestFit = bestInd.fitness.values[0]
bestIndII = []
for each in bestInd:bestI = chr(each)bestIndII.append(bestI)
print('最优解为:',str(bestIndII))
print('对应的函数最小值为:',str(bestFit))# 可视化
gen = logbook.select('gen')
min = logbook.select('min')
avg = logbook.select('avg')
plt.plot(gen,min,'b-',label = 'MIN_FITNESS')
plt.plot(gen,avg,'r-',label = 'AVG_FITNESS')
plt.xlabel('gen')
plt.plot('fit')
plt.legend(loc = 'upper right')
plt.show()

运行结果

gen  avg     std         min max
0   0.51    0.699929    0   3
0   1.26    0.687314    0   3
1   1.94    0.71861     1   4
2   2.59    0.664756    2   5
3   3.4     0.565685    3   5
4   3.98    0.599667    3   6
5   4.58    0.750733    4   7
6   5.55    0.71239     5   8
7   6.36    0.793977    5   9
8   7.22    0.944246    6   10
9   8.15    0.84113     7   11
10  9.03    0.754387    8   12
11  9.77    0.810617    9   12
12  10.53   0.623779    10  12
13  11.2    0.489898    10  12
14  11.62   0.485386    11  12
15  12      0           12  12
16  12      0           12  12
17  12      0           12  12
18  12      0           12  12
19  12      0           12  12
...
194 12      0           12  12
195 12      0           12  12
196 12      0           12  12
197 12      0           12  12
198 12      0           12  12
199 12      0           12  12
200 12      0           12  12
最优解为: ['t', 'o', 'b', 'e', 'o', 'r', 'n', 'o', 't', 'f', 'o', 'b', 'e']

可视化

小结

  • 这里给出的评价方法一的结果是多次运行后的一个较优解:[‘t’, ‘o’, ‘b’, ‘f’, ‘o’, ‘q’, ‘n’, ‘p’,
    ‘t’, ‘t’, ‘o’, ‘b’, ‘e’],它显然并非全局最优解 — 并没有能完全复现我们的目标;
  • 评价方法二的结果是多次运行中随便取了一次结果 — 它每次都能以很快的速度收敛到最优解。
  • 两个程序的差别仅仅在于更换了评价函数,别的遗传算法操作完全相同,可以看到评价函数选择对于遗传算法设计的重要性。

基于DEAP库的python进化算法--遗传算法实践--配词问题相关推荐

  1. 遗传算法 python 简书_基于DEAP库的Python进化算法从入门到入土—(二)简单遗传算法实现...

    前言 在上一篇中,我们已经介绍了如何在DEAP中实现进化算法的基本操作,在这一篇中我们试图将各个操作组装起来,用进化算法解决一个简单的一元函数寻优问题. 进化算法实例 - 一元函数寻优 问题描述与分析 ...

  2. python路线寻优_基于DEAP库的Python进化算法从入门到入土 --(四)遗传算法的改进...

    前言 前面一节我们尝试了用GA求解TSP问题,简单遗传算法总是不能很好收敛到一个较优的解,在用时和求解精度上都被贪心算法吊打.在末尾我们总结了三个可能的改进方向,这次我们想要沿着这三个方向试着改进简单 ...

  3. 基于DEAP库的Python进化算法

    https://www.jianshu.com/p/8fa044ed9267 http://geatpy.com/index.php/category/geatpy_tutorials/

  4. 基于Pyinstaller库将Python项目包括 图片打包exe方法,本人已经实践多次

    基于Pyinstaller库将Python项目包括 图片打包exe方法,本人已经实践多次 文章目录 基于Pyinstaller库将Python项目包括 图片打包exe方法,本人已经实践多次 一.前言 ...

  5. IGD+-EMOA:基于IGD+的多目标进化算法

    IGD±EMOA:基于IGD+的多目标进化算法 参考文献 <IGD±EMOA:A Multi-Objective Evolutionary Algorithm based on IGD+> ...

  6. MaOEA-IBP:带有边界保护的基于指标的多目标进化算法

    MaOEA-IBP:带有边界保护的基于指标的多目标进化算法 参考文献 <An Indicator-Based Many-Objective Evolutionary Algorithm With ...

  7. 【图像压缩】基于matlab香农熵和差分进化算法多级图像阈值图像压缩【含Matlab源码 2035期】

    一.差分进化算法简介 1 前言 在遗传.选择和变异的作用下,自然界生物体优胜劣汰,不断由低级向高级进化和发展.人们注意到,适者生存的进化规律可以模式化,从而构成一些优化算法:近年来发展的进化计算类算法 ...

  8. 进化算法--遗传算法

    遗传算法 一.能解决的问题 如果你需要解决一个问题,这个问题的每一个可能的解均可以用位串来表示,那么遗传算法就能解决这个问题. 二.术语 个体:每一个可能的解: 种群:一群个体: 基因:个体中位的一个 ...

  9. 新手题库-《Python语言程序设计》实践6

    选择题 1. 关于Python的分支结构,以下选项中描述错误的是 [ 正确答案: B] A Python中if-elif-else语句描述多分支结构 B 分支结构可以向已经执行过的语句部分跳转 C P ...

  10. Python遗传算法库和进化算法框架(二)Geatpy库函数和数据结构

    (转载自https://blog.csdn.net/qq_33353186/article/details/82020507) 上一篇讲了Geatpy的快速入门:https://blog.csdn.n ...

最新文章

  1. win10连接计算机,如何在win10中连接计算机和打印机
  2. .net core 微服务_.NET 微服务实战之负载均衡(上)
  3. mvn -U clean eclipse:clean eclipse:eclipse
  4. 国外经典!架构师必备:《MongoDB实战》第2版
  5. SQL Server中的快照隔离
  6. 原生mysql启动_单实例MySQL的启动和关闭的方法
  7. 关于使用jacob出现的异常
  8. 21、OSPF配置实验之特殊区域totally stub
  9. 计算机科学自考本科的科目,自考本科计算机专业考哪些
  10. DSP中EALLOW,EDIS,EINT,DINT,ERTM,DRTM的作用
  11. python获取今日头条搜索信息_python 爬取今日头条关键词搜索
  12. 每天学命令deleteRow
  13. svchost.exe占网速解决方法
  14. php 图片印章_php版圆形印章生成器
  15. Soft-NMS – Improving Object Detection With One Line of Code
  16. 用户输入自己的【姓名 年龄 爱好】 + 加CP【姓名 年龄 爱好】,点击按钮,页面显示该用户的信息 点击提交按钮,JSON显示用户信息+副本信息(副本初始值是{})
  17. 罗马数字和阿拉伯数字之间的转换
  18. 微信小程序自定义底部弹窗
  19. 国产芯片---带使能端、轨到轨的运算放大器MS8093
  20. nslookup type值_Nslookup命令及常见参数 - 里维斯社

热门文章

  1. 【COCOS2D-HTML5 开发之三】演示样例项目附源代码及执行的GIF效果图
  2. SharePoint 2013 中的新增功能(与开发有关)
  3. poj 1251 Jungle Roads
  4. Exchange 2003 和 Exchange 2007最大处理器数、内存支持比较
  5. 20190814 On Java8 第四章 运算符
  6. 第一章:Chrome 43 配置 java + selenium 环境
  7. 用Python自动发送邮件
  8. SharePoint 2007 在Windows Server 2008上列表Open with Windows Explorer失效 解决
  9. LC-779 语法中的第k个字符
  10. 五款app原型设计工具对比