python 如何实现遗传算法


Posted in Python onSeptember 22, 2020

1、基本概念

 遗传算法(GA)是最早由美国Holland教授提出的一种基于自然界的“适者生存,优胜劣汰”基本法则的智能搜索算法。该法则很好地诠释了生物进化的自然选择过程。遗传算法也是借鉴该基本法则,通过基于种群的思想,将问题的解通过编码的方式转化为种群中的个体,并让这些个体不断地通过选择、交叉和变异算子模拟生物的进化过程,然后利用“优胜劣汰”法则选择种群中适应性较强的个体构成子种群,然后让子种群重复类似的进化过程,直到找到问题的最优解或者到达一定的进化(运算)时间。

python 如何实现遗传算法

基因:在GA算法中,基因代表了具体问题解的一个决策变量,问题解和染色体中基因的对应关系如下所示:

python 如何实现遗传算法

种群:多个个体即组成一个种群。GA算法中,一个问题的多组解即构成了问题的解的种群。

2、主要步骤

GA算法的基本步骤如下:

Step 1. 种群初始化。选择一种编码方案然后在解空间内通过随机生成的方式初始化一定数量的个体构成GA的种群。

Step 2. 评估种群。利用启发式算法对种群中的个体(矩形件的排入顺序)生成排样图并依此计算个体的适应函数值(利用率),然后保存当前种群中的最优个体作为搜索到的最优解。

Step 3. 选择操作。根据种群中个体的适应度的大小,通过轮盘赌或者期望值方法,将适应度高的个体从当前种群中选择出来。

Step 4. 交叉操作。将上一步骤选择的个体,用一定的概率阀值Pc控制是否利用单点交叉、多点交叉或者其他交叉方式生成新的交叉个体。

Step 5. 变异操作。用一定的概率阀值Pm控制是否对个体的部分基因执行单点变异或多点变异。

Step 6. 终止判断。若满足终止条件,则终止算法,否则返回Step 2。

流程图如下所示:

python 如何实现遗传算法

3、主要操作介绍

3.1 种群初始化

种群的初始化和具体的问题有关。比如一个问题有n个决策变量{x1,x2,…,xn}。每个决策变量有取值范围:下界{L1,L2,…,Ln}和上界{U1,U2,…,Un},则种群中个体的初始化即随机地在决策变量的取值范围内生成各个决策变量的值:Xj={x1,x2,...,xn},其中xi属于范围(Li,Ui)内。所有的个体即构成种群。当每个个体都初始化后,即种群完成初始化。

3.2 评价种群

种群的评价即计算种群中个体的适应度值。假设种群population有popsize个个体。依次计算每个个体的适应度值及评价种群。

3.3 选择操作

GA算法中常见的选择操作有轮盘赌方式:种群中适应度值更优的个体被选择的概率越大。假设popsize=4,按照如下表达式计算各个个体的被选择概率的大小,然后用圆饼图表示如下。

P(Xj) = fit(Xj)/(fit(X1)+fit(X2)+fit(X3)+fit(X4)),j=1,2,3,4

python 如何实现遗传算法

当依据轮盘赌方式进行选择时,则概率越大的越容易被选择到。

3.4 交叉操作

交叉操作也有许多种:单点交叉,两点交叉等。此处仅讲解一下两点交叉。首先利用选择操作从种群中选择两个父辈个体parent1和parent2,然后随机产生两个位置pos1和pos2,将这两个位置中间的基因位信息进行交换,便得到下图所示的off1和off2两个个体,但是这两个个体中一般会存在基因位信息冲突的现象(整数编码时),此时需要对off1和off2个体进行调整:off1中的冲突基因根据parent1中的基因调整为parent2中的相同位置处的基因。如off1中的“1”出现了两次,则第二处的“1”需要调整为parent1中“1”对应的parent2中的“4”,依次类推处理off1中的相冲突的基因。需要注意的是,调整off2,则需要参考parent2。

python 如何实现遗传算法

3.5 变异操作

变异操作的话,根据不同的编码方式有不同的变异操作。

如果是浮点数编码,则变异可以就染色体中间的某一个基因位的信息进行变异(重新生成或者其他调整方案)。

python 如何实现遗传算法

如果是采用整数编码方案,则一般有多种变异方法:位置变异和符号变异。

位置变异:

python 如何实现遗传算法

符号变异:

python 如何实现遗传算法

4、Python代码

#-*- coding:utf-8 -*-

import random
import math
from operator import itemgetter

class Gene:
  '''
  This is a class to represent individual(Gene) in GA algorithom
  each object of this class have two attribute: data, size
  '''
  def __init__(self,**data):
    self.__dict__.update(data)    
    self.size = len(data['data'])#length of gene
                
    
class GA:
  '''
  This is a class of GA algorithm. 
  '''
  def __init__(self,parameter):
    '''
    Initialize the pop of GA algorithom and evaluate the pop by computing its' fitness value .
    The data structure of pop is composed of several individuals which has the form like that:
    
    {'Gene':a object of class Gene, 'fitness': 1.02(for example)}

    Representation of Gene is a list: [b s0 u0 sita0 s1 u1 sita1 s2 u2 sita2]
    
    '''
    #parameter = [CXPB, MUTPB, NGEN, popsize, low, up]
    self.parameter = parameter

    low = self.parameter[4]
    up = self.parameter[5]
    
    self.bound = []
    self.bound.append(low)
    self.bound.append(up)
    
    pop = []
    for i in range(self.parameter[3]):
      geneinfo = []
      for pos in range(len(low)):
        geneinfo.append(random.uniform(self.bound[0][pos], self.bound[1][pos]))#initialise popluation
        
      fitness = evaluate(geneinfo)#evaluate each chromosome
      pop.append({'Gene':Gene(data = geneinfo), 'fitness':fitness})#store the chromosome and its fitness
      
    self.pop = pop
    self.bestindividual = self.selectBest(self.pop)#store the best chromosome in the population
    
  def selectBest(self, pop):
    '''
    select the best individual from pop
    '''
    s_inds = sorted(pop, key = itemgetter("fitness"), reverse = False)
    return s_inds[0]
    
  def selection(self, individuals, k):
    '''
    select two individuals from pop
    '''
    s_inds = sorted(individuals, key = itemgetter("fitness"), reverse=True)#sort the pop by the reference of 1/fitness 
    sum_fits = sum(1/ind['fitness'] for ind in individuals) #sum up the 1/fitness of the whole pop
    
    chosen = []
    for i in xrange(k):
      u = random.random() * sum_fits#randomly produce a num in the range of [0, sum_fits]
      sum_ = 0
      for ind in s_inds:
        sum_ += 1/ind['fitness']#sum up the 1/fitness
        if sum_ > u:
          #when the sum of 1/fitness is bigger than u, choose the one, which means u is in the range of [sum(1,2,...,n-1),sum(1,2,...,n)] and is time to choose the one ,namely n-th individual in the pop
          chosen.append(ind)
          break
    
    return chosen  


  def crossoperate(self, offspring):
    '''
    cross operation
    '''
    dim = len(offspring[0]['Gene'].data)

    geninfo1 = offspring[0]['Gene'].data#Gene's data of first offspring chosen from the selected pop
    geninfo2 = offspring[1]['Gene'].data#Gene's data of second offspring chosen from the selected pop
    
    pos1 = random.randrange(1,dim)#select a position in the range from 0 to dim-1, 
    pos2 = random.randrange(1,dim)

    newoff = Gene(data = [])#offspring produced by cross operation
    temp = []
    for i in range(dim):
      if (i >= min(pos1,pos2) and i <= max(pos1,pos2)):
        temp.append(geninfo2[i])
        #the gene data of offspring produced by cross operation is from the second offspring in the range [min(pos1,pos2),max(pos1,pos2)]
      else:
        temp.append(geninfo1[i])
        #the gene data of offspring produced by cross operation is from the frist offspring in the range [min(pos1,pos2),max(pos1,pos2)]
    newoff.data = temp
    
    return newoff


  def mutation(self, crossoff, bound):
    '''
    mutation operation
    '''
    
    dim = len(crossoff.data)

    pos = random.randrange(1,dim)#chose a position in crossoff to perform mutation.

    crossoff.data[pos] = random.uniform(bound[0][pos],bound[1][pos])
    return crossoff
  
  def GA_main(self):
    '''
    main frame work of GA
    '''
    
    popsize = self.parameter[3]
    
    print("Start of evolution")
    
    # Begin the evolution
    for g in range(NGEN):
      
      print("-- Generation %i --" % g)   
           
      #Apply selection based on their converted fitness
      selectpop = self.selection(self.pop, popsize)  

      nextoff = []  
      while len(nextoff) != popsize:   
        # Apply crossover and mutation on the offspring      
                
        # Select two individuals
        offspring = [random.choice(selectpop) for i in xrange(2)]
        
        if random.random() < CXPB: # cross two individuals with probability CXPB
          crossoff = self.crossoperate(offspring)
          fit_crossoff = evaluate(self.xydata, crossoff.data)# Evaluate the individuals      
          
          if random.random() < MUTPB: # mutate an individual with probability MUTPB
            muteoff = self.mutation(crossoff,self.bound)
            fit_muteoff = evaluate(self.xydata, muteoff.data)# Evaluate the individuals
            nextoff.append({'Gene':muteoff,'fitness':fit_muteoff})
            
      # The population is entirely replaced by the offspring
      self.pop = nextoff
      
      # Gather all the fitnesses in one list and print the stats
      fits = [ind['fitness'] for ind in self.pop]
        
      length = len(self.pop)
      mean = sum(fits) / length
      sum2 = sum(x*x for x in fits)
      std = abs(sum2 / length - mean**2)**0.5
      best_ind = self.selectBest(self.pop)

      if best_ind['fitness'] < self.bestindividual['fitness']:
        self.bestindividual = best_ind

      print("Best individual found is %s, %s" % (self.bestindividual['Gene'].data,self.bestindividual['fitness']))
      print(" Min fitness of current pop: %s" % min(fits))
      print(" Max fitness of current pop: %s" % max(fits))
      print(" Avg fitness of current pop: %s" % mean)
      print(" Std of currrent pop: %s" % std)
    
    print("-- End of (successful) evolution --")  

if __name__ == "__main__":

  CXPB, MUTPB, NGEN, popsize = 0.8, 0.3, 50, 100#control parameters
  
  up = [64, 64, 64, 64, 64, 64, 64, 64, 64, 64]#upper range for variables
  low = [-64, -64, -64, -64, -64, -64, -64, -64, -64, -64]#lower range for variables
  parameter = [CXPB, MUTPB, NGEN, popsize, low, up]
  
  run = GA(parameter)
  run.GA_main()

以上就是python 如何实现遗传算法的详细内容,更多关于python 遗传算法的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
深入理解 Python 中的多线程 新手必看
Nov 20 Python
python模块简介之有序字典(OrderedDict)
Dec 01 Python
详解Python 协程的详细用法使用和例子
Jun 15 Python
对Python捕获控制台输出流的方法详解
Jan 07 Python
python 去除二维数组/二维列表中的重复行方法
Jan 23 Python
Python线程之定位与销毁的实现
Feb 17 Python
Python PIL读取的图像发生自动旋转的实现方法
Jul 05 Python
Python实现一个带权无回置随机抽选函数的方法
Jul 24 Python
基于Python实现剪切板实时监控方法解析
Sep 11 Python
python3实现从kafka获取数据,并解析为json格式,写入到mysql中
Dec 23 Python
python如何快速生成时间戳
Jul 21 Python
使用Python将xmind脑图转成excel用例的实现代码(一)
Oct 12 Python
利用python汇总统计多张Excel
Sep 22 #Python
爬虫代理的cookie如何生成运行
Sep 22 #Python
python 如何将office文件转换为PDF
Sep 22 #Python
Python制作一个仿QQ办公版的图形登录界面
Sep 22 #Python
Python使用for生成列表实现过程解析
Sep 22 #Python
python实现发送带附件的邮件代码分享
Sep 22 #Python
使用Python绘制台风轨迹图的示例代码
Sep 21 #Python
You might like
在命令行下运行PHP脚本[带参数]的方法
2010/01/22 PHP
php批量修改表结构实例
2017/05/24 PHP
javascript 自动转到命名锚记
2009/01/10 Javascript
使用javascipt---实现二分查找法
2013/04/10 Javascript
javascript:json数据的页面绑定示例代码
2014/01/26 Javascript
js判断页面中是否有指定控件的简单实例
2014/03/04 Javascript
JAVASCRIPT代码编写俄罗斯方块网页版
2015/11/26 Javascript
浅析JavaScript作用域链、执行上下文与闭包
2016/02/01 Javascript
js实现页面a向页面b传参的方法
2016/05/29 Javascript
window.open打开窗口被拦截的快速解决方法
2016/08/04 Javascript
JavaScript实现邮箱地址自动匹配功能代码
2016/11/28 Javascript
关于Function中的bind()示例详解
2016/12/02 Javascript
angular.js + require.js构建模块化单页面应用的方法步骤
2017/07/19 Javascript
微信小程序显示下拉列表功能【附源码下载】
2017/12/12 Javascript
关于Angularjs中跨域设置白名单问题
2018/04/17 Javascript
Vue利用History记录上一页面的数据方法实例
2018/11/02 Javascript
超好用的jQuery分页插件jpaginate用法示例【附源码下载】
2018/12/06 jQuery
VUE+elementui组件在table-cell单元格中绘制微型echarts图
2020/04/20 Javascript
[40:48]DOTA2上海特级锦标赛D组败者赛 Liquid VS COL第二局
2016/02/28 DOTA
[57:09]DOTA2-DPC中国联赛 正赛 Phoenix vs Dynasty BO3 第一场 1月26日
2021/03/11 DOTA
Python+django实现文件上传
2016/01/17 Python
详解Python静态网页爬取获取高清壁纸
2019/04/23 Python
python3实现小球转动抽奖小游戏
2020/04/15 Python
python 环境搭建 及python-3.4.4的下载和安装过程
2019/07/20 Python
宝拉珍选英国官网:Paula’s Choice英国
2019/05/29 全球购物
数学专业推荐信范文
2013/11/21 职场文书
应届实习生的自我评价范文
2014/01/05 职场文书
模范家庭事迹材料
2014/02/10 职场文书
大学生简短的自我评价分享
2014/02/20 职场文书
销售会计岗位职责
2014/03/15 职场文书
运动会演讲稿50字
2014/08/25 职场文书
骨干教师考核评语
2014/12/31 职场文书
python获取对象信息的实例详解
2021/07/07 Python
Python实现猜拳与猜数字游戏的方法详解
2022/04/06 Python
什么是Python装饰器?如何定义和使用?
2022/04/11 Python
Golang jwt身份认证
2022/04/20 Golang