遗传算法之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 相关文章推荐
pymongo实现控制mongodb中数字字段做加法的方法
Mar 26 Python
python爬取51job中hr的邮箱
May 14 Python
深入解析Python中的__builtins__内建对象
Jun 21 Python
Python错误: SyntaxError: Non-ASCII character解决办法
Jun 08 Python
Python将list中的string批量转化成int/float的方法
Jun 26 Python
面向初学者的Python编辑器Mu
Oct 08 Python
Django+Xadmin构建项目的方法步骤
Mar 06 Python
Python写一个基于MD5的文件监听程序
Mar 11 Python
Django框架 信号调度原理解析
Sep 04 Python
Python面向对象魔法方法和单例模块代码实例
Mar 25 Python
PyTorch中的C++扩展实现
Apr 02 Python
python中对列表的删除和添加方法详解
Feb 24 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
Mysql的常用命令
2006/10/09 PHP
php使用百度翻译api示例分享
2014/01/31 PHP
C#使用PHP服务端的Web Service通信实例
2014/04/08 PHP
PHP删除二维数组中相同元素及数组重复值的方法示例
2017/05/05 PHP
js获得指定控件输入光标的坐标兼容IE,Chrome,火狐等多种主流浏览器
2013/05/21 Javascript
javascript-简单的日历实现及Date对象语法介绍(附图)
2013/05/30 Javascript
JavaScript中的条件判断语句使用详解
2015/06/03 Javascript
创建一个类Person的简单实例
2016/05/17 Javascript
浅谈js对象的创建和对6种继承模式的理解和遐想
2016/10/16 Javascript
jquery实现折叠菜单效果【推荐】
2017/03/08 Javascript
NodeJS简单实现WebSocket功能示例
2018/02/10 NodeJs
react router4+redux实现路由权限控制的方法
2018/05/03 Javascript
JavaScript实现的反序列化json字符串操作示例
2018/07/18 Javascript
jquery插件实现轮播图效果
2020/10/19 jQuery
浅析VUE防抖与节流
2020/11/24 Vue.js
python中Flask框架简单入门实例
2015/03/21 Python
python中安装Scrapy模块依赖包汇总
2017/07/02 Python
python数据结构之链表的实例讲解
2017/07/25 Python
解决python中无法自动补全代码的问题
2018/12/04 Python
浅谈pandas筛选出表中满足另一个表所有条件的数据方法
2019/02/08 Python
Python实现的序列化和反序列化二叉树算法示例
2019/03/02 Python
Pytorch使用MNIST数据集实现CGAN和生成指定的数字方式
2020/01/10 Python
tensorflow 固定部分参数训练,只训练部分参数的实例
2020/01/20 Python
Python如何在main中调用函数内的函数方式
2020/06/01 Python
Django模板报TemplateDoesNotExist异常(亲测可行)
2020/12/18 Python
使用CSS禁止textarea调整大小功能的方法
2015/03/13 HTML / CSS
HTML5 canvas 基本语法
2009/08/26 HTML / CSS
优秀小学生家长评语
2014/01/30 职场文书
大学生优秀自荐信范文
2014/02/25 职场文书
房屋出售协议书
2014/04/10 职场文书
关于青春的演讲稿
2014/05/05 职场文书
财务会计专业求职信
2014/06/09 职场文书
搞笑车尾标语
2014/06/23 职场文书
信仰心得体会
2014/09/05 职场文书
弘扬焦裕禄精神走群众路线思想汇报
2014/09/12 职场文书
女性健康知识讲座通知
2015/04/23 职场文书