遗传算法之Python实现代码


Posted in Python onOctober 10, 2017

写在前面

之前的文章中已经讲过了遗传算法的基本流程,并且用MATLAB实现过一遍了。这一篇文章主要面对的人群是看过了我之前的文章,因此我就不再赘述遗传算法是什么以及基本的内容了,假设大家已经知道我是怎么写遗传算法的了。

Python的遗传算法主函数

我的思想是,创建一个染色体的类,其中包括了两个变量:染色体chrom与适应度fitness。因此我们就可以通过直接建立对象来作为种群中的个体。

#染色体的类
class Chrom:
  chrom = []
  fitness = 0
  def showChrom(self):
    print(self.chrom)
  def showFitness(self):
    print(self.fitness)

所以我们开始设置基础参数。其中种群的表达方式我用的是字典,也就是用一个字典来保存种群内的所有个体,这个也是我想出来的创建多个对象的方法。

将字典的索引为个体的标号,如:chrom1, chrom2等。字典索引的值就是一个对象。这个对象拥有两个属性,就是染色体与适应度。

其实在这一方便来说,我觉得在思路上是优于利用MATLAB的矩阵式编程的。因为这样可以很直观的将个体与个体的属性这一种思想给表达出来,相比一堆矩阵来说,在逻辑上比较容易接受。

#基础参数
N = 200 #种群内个体数目
mut = 0.2 #突变概率
acr = 0.2 #交叉概率

pop = {} #存储染色体的字典
for i in range(N):
  pop['chrom'+str(i)] = Chrom()
chromNodes = 2 #染色体节点数(变量个数)
iterNum = 10000 #迭代次数
chromRange = [[0, 10], [0, 10]] #染色体范围
aveFitnessList = [] #平均适应度
bestFitnessList = [] #最优适应度

之后就是初始染色体了,其中就牵扯到了各种用来初始化种群、计算适应度、找最优等函数,我在这里分出了两个文件,分别为Genetic.py与Fitness.py。

Genetic.py里面有八个函数,主要包含了作用于种群或者染色体操作的函数,分别为:

  1. findBest函数,用于寻找种群中的最优染色体;
  2. findworse函数,用于寻找种群中的最劣染色体;
  3. initialize函数,用于初始化种群;
  4. calAveFitness函数,用于计算种群的平均适应度;
  5. mutChrom函数,用于对染色体进行变异;
  6. inRange函数,用于判断染色体节点值是否越界;
  7. acrChrom函数,用于对染色体进行交叉;
  8. compareChrom函数,用于比较两个染色体孰优孰劣。

Fitness.py里面有两个函数,主要包含了对适应度操作的函数,分别为:

  1. calFitness函数,用来迭代每一个个体,并计算适应度(利用funcFitness函数计算);
  2. funcFitness函数,计算单个个体的适应度。

因此可以列出初始化代码为

#初始染色体
pop = Genetic.initialize(pop, chromNodes, chromRange)
pop = Fitness.calFitness(pop) #计算适应度
bestChrom = Genetic.findBest(pop) #寻找最优染色体
bestFitnessList.append(bestChrom[1]) #将当前最优适应度压入列表中
aveFitnessList.append(Genetic.calAveFitness(pop, N)) #计算并存储平均适应度

迭代过程的思路和逻辑与MATLAB无异

#开始迭代
for t in range(iterNum):
  #染色体突变
  pop = Genetic.mutChrom(pop, mut, chromNodes, bestChrom, chromRange)
  #染色体交换
  pop = Genetic.acrChrom(pop, acr, chromNodes)
  #寻找最优
  nowBestChrom = Genetic.findBest(pop)
  #比较前一个时间的最优和现在的最优
  bestChrom = Genetic.compareChrom(nowBestChrom, bestChrom)
  #寻找与替换最劣
  worseChrom = Genetic.findWorse(pop)
  pop[worseChrom[0]].chrom = pop[bestChrom[0]].chrom.copy()
  pop[worseChrom[0]].fitness = pop[bestChrom[0]].fitness
  #存储最优与平均
  bestFitnessList.append(bestChrom[1])
  aveFitnessList.append(Genetic.calAveFitness(pop, N))

最后再做一下迭代的的图像

plt.figure(1)
plt.plot(x, aveFitnessList)
plt.plot(x, bestFitnessList)
plt.show()

最后再在最前面加上各种库和文件就可以运行了。

import Genetic
import Fitness
import matplotlib.pyplot as plt
import numpy as np

感悟

可以说最主要的感悟就是染色体这一个类。其实那个Genetic.py与Fitness.py这两个文件也可以直接包装成类,但是这样一来我就嫌主文件太臃肿,在其他里面再包装成类又多此一举,毕竟这只是一个小程序,所以我就这样写了。

深刻感悟到了面向对象编程的优点,在编程逻辑的处理上真是一种享受,只需要思考对象的属性即可,省去了许多复杂的思考。

另一个感悟就是创建多个对象时,利用字典的方法来创建对象。当初我也是困惑怎么建立一个类似于C++中的对象数组,上网查找了各种方法,结果都避而不谈(当然,也可能是我搜索能力太差没找到),所以经过尝试中遇到到了这种方法。

等有空我再详细说一下这个方法吧,这一次就先到这里。

剩余的函数补充

首先是Genetic.py里面的八个函数

import random

#寻找最优染色体
def findBest(pop):
  best = ['1', 0.0000001]
  for i in pop:
    if best[1] < pop[i].fitness:
      best = [i, pop[i].fitness]
  return best

#寻找最劣染色体
def findWorse(pop):
  worse = ['1', 999999]
  for i in pop:
    if worse[1] > pop[i].fitness:
      worse = [i, pop[i].fitness]
  return worse

#赋初始值
def initialize(pop, chromNodes, chromRange):
  for i in pop:
    chromList = []
    for j in range(chromNodes):
      chromList.append(random.uniform(chromRange[j][0], chromRange[j][1]+1))
    pop[i].chrom = chromList.copy()
  return pop

#计算平均适应度
def calAveFitness(pop, N):
  sumFitness = 0
  for i in pop:
    sumFitness = sumFitness + pop[i].fitness
  aveFitness = sumFitness / N
  return aveFitness

#进行突变
def mutChrom(pop, mut, chromNodes, bestChrom, chromRange):
  for i in pop:
    #如果随机数小于变异概率(即可以变异)
    if mut > random.random():
      mutNode = random.randrange(0,chromNodes)
      mutRange = random.random() * (1-pop[i].fitness/bestChrom[1])**2
      pop[i].chrom[mutNode] = pop[i].chrom[mutNode] * (1+mutRange)
      #判断变异后的范围是否在要求范围内
      pop[i].chrom[mutNode] = inRange(pop[i].chrom[mutNode], chromRange[mutNode])
  return pop

#检验便宜范围是否在要求范围内
def inRange(mutNode, chromRange):
  if chromRange[0] < mutNode < chromRange[1]:
    return mutNode
  elif mutNode-chromRange[0] > mutNode-chromRange[1]:
    return chromRange[1]
  else:
    return chromRange[0]

#进行交叉
def acrChrom(pop, acr, chromNodes):
  for i in pop:
    for j in pop:
      if acr > random.random():
        acrNode = random.randrange(0, chromNodes)
        #两个染色体节点进行交换
        pop[i].chrom[acrNode], pop[j].chrom[acrNode] = pop[j].chrom[acrNode], pop[i].chrom[acrNode]
  return pop

#进行比较
def compareChrom(nowbestChrom, bestChrom):
  if bestChrom[1] > nowbestChrom[1]:
    return bestChrom
  else:
    return nowbestChrom

然后是Fitness.py的两个函数

import math

def calFitness(pop):
  
  for i in pop:
    #计算每个染色体的适应度
    pop[i].fitness = funcFitness(pop[i].chrom)

  return pop

def funcFitness(chrom):
  #适应度函数
  fitness = math.sin(chrom[0])+math.cos(chrom[1])+0.1*(chrom[0]+chrom[1])

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python实现微信公众平台自定义菜单实例
Mar 20 Python
python实现定时同步本机与北京时间的方法
Mar 24 Python
使用python3+xlrd解析Excel的实例
May 04 Python
Python Grid使用和布局详解
Jun 30 Python
python numpy元素的区间查找方法
Nov 14 Python
python协程之动态添加任务的方法
Feb 19 Python
Python 获取项目根路径的代码
Sep 27 Python
使用Python实现分别输出每个数组
Dec 06 Python
Python 利用OpenCV给照片换底色的示例代码
Aug 03 Python
python将数据插入数据库的代码分享
Aug 16 Python
Python容器类型公共方法总结
Aug 19 Python
Python获取百度热搜的完整代码
Apr 07 Python
Python使用arrow库优雅地处理时间数据详解
Oct 10 #Python
Python使用getpass库读取密码的示例
Oct 10 #Python
Python 逐行分割大txt文件的方法
Oct 10 #Python
Python输出带颜色的字符串实例
Oct 10 #Python
python中使用正则表达式的连接符示例代码
Oct 10 #Python
python利用正则表达式排除集合中字符的功能示例
Oct 10 #Python
python 上下文管理器使用方法小结
Oct 10 #Python
You might like
php 学习资料零碎东西
2010/12/04 PHP
Zend Framework教程之Autoloading用法详解
2016/03/08 PHP
phpMyAdmin无法登陆的解决方法
2017/04/27 PHP
Laravel源码解析之路由的使用和示例详解
2018/09/27 PHP
jquery validate poshytip 自定义样式
2012/11/26 Javascript
2012年开发人员的16款新鲜的jquery插件体验分享
2012/12/28 Javascript
jquery全选/全不选/反选另一种实现方法(配合原生js)
2013/04/07 Javascript
js创建表单元素并使用submit进行提交
2014/08/14 Javascript
jQuery数据缓存用法分析
2015/02/20 Javascript
JS实现黑客帝国文字下落效果
2015/09/01 Javascript
JS实现重新加载当前页面
2016/11/29 Javascript
easyui datebox 时间限制,datebox开始时间限制结束时间,datebox截止日期比起始日期大的实现代码
2017/01/12 Javascript
webpack配置之后端渲染详解
2017/10/26 Javascript
vue2手机APP项目添加开屏广告或者闪屏广告
2017/11/28 Javascript
对vue中v-on绑定自定事件的实例讲解
2018/09/06 Javascript
JavaScript实现简单的计算器
2020/01/16 Javascript
javascript使用canvas实现饼状图效果
2020/09/08 Javascript
Python实现压缩和解压缩ZIP文件的方法分析
2017/09/28 Python
python使用正则表达式的search()函数实现指定位置搜索功能
2017/11/10 Python
解析Python3中的Import
2019/10/13 Python
把vgg-face.mat权重迁移到pytorch模型示例
2019/12/27 Python
html5中 media(播放器)的api使用指南
2014/12/26 HTML / CSS
html5写一个BUI折叠菜单插件的实现方法
2019/09/11 HTML / CSS
英国著名音像制品和图书游戏购物网站:Zavvi
2016/08/04 全球购物
中国医药集团国药在线:国药网
2017/02/06 全球购物
Emporio Armani腕表天猫官方旗舰店:乔治·阿玛尼为年轻人设计的副线品牌
2017/07/02 全球购物
施华洛世奇日本官网:SWAROVSKI日本
2018/05/04 全球购物
英国羊绒服装购物网站:Pure Collection
2018/10/22 全球购物
The North Face北面法国官网:美国著名户外品牌
2019/11/01 全球购物
外贸英语毕业生自荐信
2013/11/14 职场文书
幼儿园优秀教师事迹
2014/02/13 职场文书
教师职业道德事迹材料
2014/08/18 职场文书
推广活动策划方案
2014/08/23 职场文书
logback 实现给变量指定默认值
2021/08/30 Java/Android
baselines示例程序train_cartpole.py的ImportError
2022/05/20 Python
数据设计之权限的实现
2022/08/05 MySQL