遗传算法之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 RuntimeError: thread.__init__() not called解决方法
Apr 28 Python
Django自定义用户认证示例详解
Mar 14 Python
Win10下python 2.7.13 安装配置方法图文教程
Sep 18 Python
深入浅析python3中的unicode和bytes问题
Jul 03 Python
python实现高斯(Gauss)迭代法的例子
Nov 20 Python
15行Python代码实现免费发送手机短信推送消息功能
Feb 27 Python
python中tab键是什么意思
Jun 18 Python
详解scrapy内置中间件的顺序
Sep 28 Python
python GUI计算器的实现
Oct 09 Python
jupyter notebook保存文件默认路径更改方法汇总(亲测可以)
Jun 09 Python
Python函数式编程中itertools模块详解
Sep 15 Python
pycharm无法安装cv2模块问题
May 20 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
PHP5.5和之前的版本empty函数的不同之处
2014/06/13 PHP
PHP模板引擎Smarty内置变量调解器用法详解
2016/04/11 PHP
创建一个复制UBB软件信息的链接或按钮的js代码
2008/01/06 Javascript
更换select下拉菜单背景样式的实现代码
2011/12/20 Javascript
jQuery获取上传文件的名称的正则表达式
2015/05/21 Javascript
浅析JS动态创建元素【两种方法】
2016/04/20 Javascript
JavaScript中的ParseInt(&quot;08&quot;)和“09”返回0的原因分析及解决办法
2016/05/19 Javascript
jQuery学习笔记——jqGrid的使用记录(实现分页、搜索功能)
2016/11/09 Javascript
JS数字千分位格式化实现方法总结
2016/12/16 Javascript
Angular动态添加、删除输入框并计算值实例代码
2017/03/29 Javascript
原生javascript实现文件异步上传的实例讲解
2017/10/26 Javascript
JS实现的哈夫曼编码示例【原始版与修改版】
2018/04/22 Javascript
vue 修改 data 数据问题并实时显示的方法
2018/08/27 Javascript
javascrit中undefined和null的区别详解
2019/04/07 Javascript
Nodejs异步流程框架async的方法
2019/06/07 NodeJs
Vue使用lodop实现打印小结
2019/07/06 Javascript
jquery实现自定义树形表格的方法【自定义树形结构table】
2019/07/12 jQuery
Javascript ParentNode和ChildNode接口原理解析
2020/03/16 Javascript
JavaScript实现像雪花一样的Hexaflake分形
2020/07/07 Javascript
vue 调用 RESTful风格接口操作
2020/08/11 Javascript
Python语言描述连续子数组的最大和
2018/01/04 Python
django缓存配置的几种方法详解
2018/07/16 Python
Python中的asyncio代码详解
2019/06/10 Python
Django 对IP访问频率进行限制的例子
2019/08/30 Python
tensorflow通过模型文件,使用tensorboard查看其模型图Graph方式
2020/01/23 Python
Columbia美国官网:美国著名的户外服装品牌
2016/11/24 全球购物
百联网上商城:i百联
2017/01/28 全球购物
香港时尚女装购物网站:ZAFUL
2017/07/19 全球购物
乌克兰移动电子产品和相关配件的在线商店:iTMag
2020/03/16 全球购物
感恩寄语大全
2014/04/11 职场文书
实习报告评语
2014/04/26 职场文书
幼儿园师德演讲稿
2014/05/06 职场文书
2016暑期师德培训心得体会
2016/01/09 职场文书
PHP中->和=>的意思
2021/03/31 PHP
详解JS WebSocket断开原因和心跳机制
2021/05/07 Javascript
Axios代理配置及封装响应拦截处理方式
2022/04/07 Vue.js