Python 遗传算法实现字符串

流程

1. 初始化

2. 适应度函数

3. 选择

4. 交叉

5. 变异

适应度函数计算方法

计算个体间的差:分别计算每个元素与目标元素的差取平方和

种群:计算总体均值

操作 说明
编码方式 ASCII码
种群规模 5000
初始种群的个体取值范围 !!!!!!!!!!!!!!!!!!
(33,33,33,33,33,33,33,33,33
,33,33,33,33,33,33,33,33,33)
~
``````````````````
(126,126,126,126,126,126,126,126,126,
126,126,126,126,126,126,126,126,126)
选择操作 个体选择概率
分配策略 根据概率保留对应个数
个体选择方法 锦标赛选择方法
交叉概率 0.7
交叉方式 多点交叉
变异方式 随机多点突变
最大迭代步数 500

效果图

小结

  • 一开始我设计的选择方法是把低于平均的个体淘汰,但是这样操作会导致陷入局部最优,循环500次依旧没有结果,很难找到最优个体。后面仔细看书,用书上的锦标赛算法,提高了随机性,可以找到了目标序列。
  • 根据流程,我发现经过几轮的遗传,种群规模会迅速下降,因为中间补充的个体数量无法抵消淘汰的个体数量。于是我根据种群规模设计了阶梯式的概率,以便可以维持种群规模。

  • 对于上面的问题,我开始想在选择后立即补充
    即 y=100/7+0.05x(x为选择后剩余的种群数量),但是补充的内容无法实现最后的功能:1.补充随机新个体,这就和选择前的操作无异,种群适应度没有太大变化。2.补充选择后的个体,会导致陷入局部最优,种群发展速度慢。3.综合 1 2 补充,
    依旧没有明显效果。
  • 书上的最优概率,(主要是突变的概率非常低)对于产生新个体的速度较慢,基因重组的效果感觉不够明显,很容易陷入局部最优和陷入一个死局面,需要许久才能跳出这个局面

  • 后面我自己修改了概率,依旧有这种问题,目前还没解决。
  • 这次的代码写的比较不合理,高耦合。有许多地方可以改进,避免大量重复循环,以提高程序执行效率

补充

  • 关于补充选择淘汰的个体,我发现可以在cross,即基因重组中改变他后代产生的children个数,直到恢复到设置的种群规模。在基因突变部分,不再是往种群中添加新的个体,而是修改现有种群的基因。
#coding=utf-8
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import randombest = [72, 101, 108, 108, 111, 44, 105,99,106,98,64,102,111,120,109,97,105,108]
#最佳序列def get_ran(b=33,e=126):"""获取随机字符值,默认从可显示字符开始(33-126)"""return random.randint(b,e)def get_pos(cou=17):"""获取随机位置,默认到17"""return random.randint(0,cou)class Chromosome:"""染色体类"""def __init__(self,dna=None):"""初始化,可指定DNA序列顺序,默认DNA为随机序列。"""if dna is not None:self.dna = dna[:]else :self.dna = []for i in range(18):self.dna.append(get_ran())def to_asc(self):"""将DNA序列由int转为str"""str = ''for chrx in self.dna:str = str + chr(chrx)return strdef __str__(self):"""将DNA序列由int转为str"""str = ''for chrx in self.dna:str = str + chr(chrx)return strdef mutation(self,which=-1):"""变异操作,默认产生随机个变异位点,突变为随机值,可指定突变位置"""if which == -1 :i = get_pos()for x in range(i):self.dna[get_pos()] = get_ran()else :self.dna[which]=get_pos()def comp(self,other):"""计算与指定序列DNA的平方差"""l = []val = 0for x in range(18):#print(x)d = self.dna[x] - other.dna[x]d = pow(d,2)l.append(d)val = val + dreturn l,valdef cross(self,other):"""该染色体与其他染色体基因重组,产生新染色体,采用多点交叉"""new = []for i in range(18):if get_pos(1) == 0:new.append(self.dna[i])else :new.append(other.dna[i])return Chromosome(new)class Population:"""种群类"""def __init__(self,much=5000,aim=[72, 101, 108, 108, 111, 44, 105,99,106,98,64,102,111,120,109,97,105,108]):"""初始化种群,默认种群数量5000,指定序列为 Hello,icjb@foxmail"""self.group = []self.best = Chromosome(aim)i = 0while i < much:self.group.append(Chromosome())i = i + 1def choice(self,p=0.05):"""选择操作,采用锦标赛选择方法,默认保留0.05"""group = []old = self.group[:]count = int(self.group.__len__() * p)once = int(self.group.__len__() / count)t_b = old[0]t = 0for ch in old:if t == once:group.append(t_b)t_b = cht = 0_,v1 = t_b.comp(self.best)_,v2 = ch.comp(self.best)if v1 >= v2 :t_b = cht = t + 1self.group.clear()self.group = group[:]def cross(self,p=0.7):"""交叉操作,采用多点交叉"""count = int(self.group.__len__()*p)i = 0group = []while i < count:t = self.group.__len__()group.append(self.group[get_pos(t-1)].cross(self.group[get_pos(t-1)]))i = i + 1self.group = self.group + groupdef mutation(self,p=0.001):"""种群突变"""count = int(self.group.__len__()*p)i = 0t = self.group.__len__()while i < count:self.group[get_pos(t-1)].mutation()i = i + 1def have_the_best(self):"""判断是否存在目标序列"""for ch in self.group:_,v = ch.comp(self.best)if v == 0 :return Truereturn Falsedef value(self):"""计算该种群的估值"""val = 0for ch in self.group:_,v = ch.comp(self.best)val = val + vreturn val / self.group.__len__()def get_best(self):"""获取种群最优个体"""best_one = self.group[0]_,val = best_one.comp(self.best)for ch in self.group:_,v = ch.comp(self.best)if val >= v :best_one = chval = vreturn best_onedef big_up(self):self.choice(0.9)self.cross(1.5)self.mutation(0.01)def big_down(self):self.choice()self.cross()self.mutation()def main():"""主函数"""ch_b = Chromosome(best)po = Population(5000)i = 1vals = []popu = []while i <= 500:val = po.value()leng = po.group.__len__()str1 = '第 {:^4} 代: 数量为 {:^6},  估值 :{:^6}'.format(i,leng,int(val))str2 = ' -- 最佳 : {}'.format(po.get_best().to_asc())if po.group.__len__() < 500:#种群个体少于500,需要补充大量新个体以免灭亡p1 = 0.8p2 = 1p3 = 0.12elif po.group.__len__() < 2500:p1 = 0.6p2 = 0.99p3 = 0.1elif po.group.__len__() < 5000:p1 = 0.5p2 = 0.9p3 = 0.09elif po.group.__len__() < 8000:p1 = 0.3p2 = 0.82p3 = 0.08elif po.group.__len__() < 10000:p1 = 0.2p2 = 0.78p3 = 0.05else :#默认操作p1 = 0.05p2 = 0.7p3 = 0.001# #但估值趋于稳定时,刺激种群# if val < 1000 :#     p1 = p1 - 0.5#     if p1 <= 0 :#         p1 = 0.05#     p2 = p2 + 0.3#     p3 = p3 + 0.05#模拟突增突降,可选# if get_pos(100) < 5 :#     po.big_down()#     print('big-down')# if get_pos(100) > 95 :#     po.big_up()#     print('big-up')print(str1+str2)#print(str2)po.choice(p1)if po.have_the_best() :print('找到目标!')print(ch_b.to_asc())breakpo.cross(p2)po.mutation(p3)vals.append(val)popu.append(leng)i = i + 1#绘图plt.figure(1)plt.subplot(121)x = range(i-1)y = vals[:]plt.plot(x,y)plt.subplot(122)y = popu[:]plt.plot(x,y)plt.show()if __name__ == "__main__":""""""main()input()

参考

遗传算法(python版) - 远方不远 - CSDN博客

一文读懂遗传算法工作原理(附Python实现)

【算法】超详细的遗传算法(Genetic Algorithm)解析 - 简书

遗传算法学习笔记(一):常用的选择策略 - 依然传奇 - 博客园

遗传算法选择策略比较 - 道客巴巴

基于遗传算法的人工智能实例之拼图游戏(python实现) - 不基调的博客 - CSDN博客

另一版本实现方式,改自GITHUB:

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import timefrom random import (choice, random, randint)__all__ = ['Chromosome', 'Population']class Chromosome:_target_gene = "Hello, icjb@foxmail.com"def __init__(self, gene):self.gene = geneself.fitness = Chromosome._update_fitness(gene)def mate(self, mate):pivot = randint(0, len(self.gene) - 1)gene1 = self.gene[:pivot] + mate.gene[pivot:]gene2 = mate.gene[:pivot] + self.gene[pivot:]        return Chromosome(gene1), Chromosome(gene2)def mutate(self):gene = list(self.gene)delta = randint(44, 122)idx = randint(0, len(gene) - 1)gene[idx] = chr((ord(gene[idx]) + delta) % 123)return Chromosome(''.join(gene))@staticmethod            def _update_fitness(gene):fitness = 0for a, b in zip(gene, Chromosome._target_gene):fitness += abs(ord(a) - ord(b))          return fitness@staticmethoddef gen_random():gene = []for x in range(len(Chromosome._target_gene)):gene.append(chr(randint(44, 122)))return Chromosome(''.join(gene))class Population:_tournamentSize = 3def __init__(self, size=1024, crossover=0.8, elitism=0.1, mutation=0.3):self.elitism = elitismself.mutation = mutationself.crossover = crossoverbuf = []for i in range(size): buf.append(Chromosome.gen_random())self.population = list(sorted(buf, key=lambda x: x.fitness))def _tournament_selection(self):best = choice(self.population)for i in range(Population._tournamentSize):cont = choice(self.population)if (cont.fitness < best.fitness): best = contreturn bestdef _selectParents(self):                 return (self._tournament_selection(), self._tournament_selection())def evolve(self):size = len(self.population)idx = int(round(size * self.elitism))buf = self.population[:idx]while (idx < size):if random() <= self.crossover:(p1, p2) = self._selectParents()children = p1.mate(p2)for c in children:if random() <= self.mutation:buf.append(c.mutate())else:buf.append(c)idx += 2else:if random() <= self.mutation:buf.append(self.population[idx].mutate())else:buf.append(self.population[idx])idx += 1self.population = list(sorted(buf[:size], key=lambda x: x.fitness))if __name__ == "__main__":maxGenerations = 2000t1 = time.time()pop = Population(size=2000, crossover=0.7, elitism=0.05, mutation=0.9)li = []x = []for i in range(1, maxGenerations + 1):print("Generation %d  Fitness:%d  Result:%s" % (i, Chromosome._update_fitness(pop.population[0].gene),pop.population[0].gene) )if pop.population[0].fitness == 0: breakelse:pop.evolve()li.append(Chromosome._update_fitness(pop.population[0].gene))xx = 0for p in range(pop.population.__len__()):xx += Chromosome._update_fitness(pop.population[p].gene)xx = xx / pop.population.__len__()x.append(xx)x.sort()print(x[0])print("Maximum generations reached without success.")t2 = time.time()t = int(t2 - t1)print(f'+ 共用时: {t} s')plt.figure(1)plt.subplot(111)x = range(i-1)y = li[:]plt.plot(x,y)plt.xlabel("generation",fontsize=12)plt.ylabel("fitness",fontsize=12)plt.show()

转载于:https://www.cnblogs.com/boxker/p/10720222.html

Python 遗传算法实现字符串相关推荐

  1. python时间日期字符串各种

    python时间日期字符串各种 python时间日期字符串各种 第一种 字符串转换成各种日期 time 库 # -*- coding: utf-8 -*- import time, datetime ...

  2. python正则取字符串日期_python 正则表达式获取字符串中所有的日期和时间

    提取日期前的处理 1.处理文本数据的日期格式统一化 text = "2015年8月31日,衢州元立金属制品有限公司仓储公司(以下简称元立仓储公司)成品仓库发生一起物体打击事故,造成直接经济损 ...

  3. 这个VS Code扩展可以自动生成Python文档字符串

    机器之心报道 编辑:魔王 该扩展利用可处理编程语言和自然语言的预训练模型 CodeBERT,实现快速生成 Python 文档字符串的功能. Visual Studio Code(简称 VS Code) ...

  4. python实现加密字符串_Python实现对字符串的加密解密方法示例

    本文实例讲述了Python实现对字符串的加密解密方法.分享给大家供大家参考,具体如下: 需求是是要将密码存在数据库里,所以要加密解密是可逆的,在数据库里不要有特殊字符,防止数据库备份和恢复中出错. 安 ...

  5. python代码统计字符串中大写字符、小写字符、特殊字符以及数值字符出现的次数

    python代码统计字符串中大写字符.小写字符.特殊字符以及数值字符出现的次数 #python代码统计字符串中大写字符.小写字符.特殊字符以及数值字符出现的次数 import restring = & ...

  6. python pandas DataFrame 字符串转日期格式

    python pandas DataFrame 字符串转日期格式 import pandas as pd import numpy as np df1 = pd.DataFrame({'日期': [' ...

  7. 超详细的Python中的字符串常识【赶紧收藏】

    今天我们说说字符串类型,涉及很多基础知识,不过字符串还是需要在多讲讲的. 回顾一下:字符串与长字符串 Python非常简单,并没有专门分出一个char(Character)类型(搞过C/Java的同学 ...

  8. 利用CodeBERT,这个VS Code扩展可以自动生成Python文档字符串

    点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送达 来自:机器之心 该扩展利用可处理编程语言和自然语言的预训练模型 CodeBERT,实现 ...

  9. CrazyWing:Python自动化运维开发实战 八、Python数据类型之字符串

    导语: 字符串是Python中最常用的数据类型,它是编程语言中表示文本的数据类型. 使用引号('或")来创建字符串. 创建字符串 只要为变量分配一个值即可. 例如: var1 = 'Hell ...

最新文章

  1. 全面收紧!继新加坡后,又一地拟暂停数据中心建设
  2. 【机器学习基础】深入理解极大似然估计(MLE) 1: 引入问题
  3. 掌握这 20 个容器实战技巧!
  4. 解决Exchange2010中无法显示客户端访问服务器ClientAccessArray中成员的问题
  5. 在JDK 10中不可变与不可修改
  6. 简单的C语言五子棋(两种模式:移动光标输入坐标和移动光标按键)
  7. 【Tomcat源码学习】-2.容器管理
  8. Linux系统下的多线程编程入门
  9. 验证手机号码归属地_excel函数爬取网页手机号码归属地,1.1%的人还不会!
  10. 误删微软应用商店怎么装回来
  11. c++采集声卡输出_基于C++Builder的声卡数据实时采集的实现
  12. 《操作系统》信号量机制
  13. Googgle guava ImmutableCollections
  14. DMSP/OLS夜间灯光遥感影像数据概述
  15. PCB板材及叠层结构(转)
  16. php电商开源框架,Sylius 开源PHP电商解决方案
  17. 一节双曲型方程基于MATLAB的求解,二维双曲型方程的分组并行格式及其数值实验...
  18. 正弦信号发生器(A题)
  19. Hadoop Yarn ResourceManager启动失败
  20. respond.js IE8使用

热门文章

  1. 银行招考计算机专业考什么,银行笔试一般都考什么?
  2. hazelcast 搭建_Spring Boot集成Hazelcast实现集群与分布式内存缓存
  3. 电源高性能和平衡区别 文件服务器,win10电源高性能和平衡区别具体有哪些细节...
  4. 游戏运营杂谈之------达克效应的启示
  5. B. Shifting Sort(rotate函数旋转应用)
  6. 数据集成技术概述-常见的CDC方案比对
  7. 安卓开发良好的习惯(想到就更新)
  8. Windows下JPBC库的使用
  9. window11离线安装android子系统步骤
  10. 60分钟吃掉嘎嘣脆的DeepCross模型