遗传算法之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函数参数*args**kwargs用法实例
Dec 04 Python
Python实现网络端口转发和重定向的方法
Sep 19 Python
Python爬取数据并写入MySQL数据库的实例
Jun 21 Python
pycharm 实现显示project 选项卡的方法
Jan 17 Python
PyQt5根据控件Id获取控件对象的方法
Jun 25 Python
python hough变换检测直线的实现方法
Jul 12 Python
通过Python编写一个简单登录功能过程解析
Sep 04 Python
selenium+Chrome滑动验证码破解二(某某网站)
Dec 17 Python
python图形开发GUI库pyqt5的详细使用方法及各控件的属性与方法
Feb 14 Python
Python函数参数分类原理详解
May 28 Python
python爬虫之selenium库的安装及使用教程
May 23 Python
Pandas数据类型之category的用法
Jun 28 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小教程之实现双向链表
2014/06/12 PHP
PHP实现生成唯一会员卡号
2015/08/24 PHP
WordPress中编写自定义存储字段的相关PHP函数解析
2015/12/25 PHP
基于PHP常用文件函数和目录函数整理
2017/08/17 PHP
php实现断点续传大文件示例代码
2020/06/19 PHP
PHP如何使用array_unshift()在数组开头插入元素
2020/09/01 PHP
Alliance vs AM BO3 第一场2.13
2021/03/10 DOTA
学习YUI.Ext 第二天
2007/03/10 Javascript
Jquery带搜索框的下拉菜单
2013/05/06 Javascript
使用delegate方法为一个tr标签加一个链接
2014/06/27 Javascript
jQuery模拟原生态App上拉刷新下拉加载更多页面及原理
2015/08/10 Javascript
jQuery UI库中dialog对话框功能使用全解析
2016/04/23 Javascript
自己封装的一个原生JS拖动方法(推荐)
2016/11/22 Javascript
jQuery实现的省市联动菜单功能示例【测试可用】
2017/01/13 Javascript
React中jquery引用的实现方法
2017/09/12 jQuery
vue.js中npm安装教程图解
2018/04/10 Javascript
浅谈手写node可读流之流动模式
2018/06/01 Javascript
解决vue的 v-for 循环中图片加载路径问题
2018/09/03 Javascript
js异步上传多张图片插件的使用方法
2018/10/22 Javascript
jQuery实现B2B网站后台管理系统侧导航
2020/07/08 jQuery
Vue 样式切换及三元判断样式关联操作
2020/08/09 Javascript
[52:27]2018DOTA2亚洲邀请赛 3.31 小组赛B组 paiN vs Secret
2018/04/01 DOTA
python中常用的九种预处理方法分享
2016/09/11 Python
对python的文件内注释 help注释方法
2018/05/23 Python
pandas值替换方法
2018/07/10 Python
pyqt5 QProgressBar清空进度条的实例
2019/06/21 Python
python动态进度条的实现代码
2019/07/03 Python
Python帮你识破双11的套路
2019/11/11 Python
详解Tensorflow不同版本要求与CUDA及CUDNN版本对应关系
2020/08/04 Python
用python监控服务器的cpu,磁盘空间,内存,超过邮件报警
2021/01/29 Python
numpy实现RNN原理实现
2021/03/02 Python
JackJones官方旗舰店:杰克琼斯男装
2018/03/27 全球购物
七年级英语教学反思
2014/01/15 职场文书
党政领导班子群众路线对照检查材料
2014/10/26 职场文书
离婚承诺书格式范文
2015/05/04 职场文书
微信小程序结合ThinkPHP5授权登陆后获取手机号
2021/11/23 PHP