纯Python实现遗传算法详解

 更新时间:2023年08月11日 09:16:31   作者:微小冷  
遗传算法(GA)是七十年代被霍兰德提出来的,那还是8086的时代,但在如今的3nm时代,仍然散发着经典的光辉,下面我们就来看看如何利用Python实现遗传算法吧

遗传算法(GA)是七十年代被霍兰德提出来的,那还是8086的时代。但在如今的3nm时代,仍然散发着经典的光辉,故而堪称跨时代的优秀算法了。

GA的核心概念是种群,种群的关键是染色体,随着自然选择,染色体通过不断地复制、交叉、突变,完成一代又一代的进化,最终得到最优的结果。

具体编程时,染色体可用字符串或者二进制进行编码;自然选择,就是适应度函数;进化就是迭代。所以技术上的关键点,就是复制、交叉、突变等过程的函数实现。

编码

考虑到二进制编码存在位数限制,故而遗传算法第一步就是确定问题规模,例如解空间在(0,1)区间,精度要求为10−6,则共涉及到106个解,需要24位二进制才能表示完全。如果有N个变量,则共计需要24N个0/1组成序列。

接下来实现一个编码函数,输入为变量数组、变量区间以及精度要求。

# x为变量,xL为解范围的最小值,pre为精度,N为二进制解的个数
def codeOne(x, xL, pre, N):
    x = int((x-xL)/pre)
    return [(x//2**i)%2 for i in range(N)]
from itertools import chain
# xs为一组变量, xL, xR为变量区间, pre为精度
def coding(xs, xL, xR, pre):
    N = int(np.ceil(np.log2((xR-xL)/pre)))
    xs = [codeOne(x, xL, pre, N) for x in xs]
    return np.array(list(chain(*xs)))
# 解码是编码的逆过程
def decodeOne(b, xL, pre, N):
    x = np.sum([b[i]*2**i for i in range(N)])
    return xL + x*pre
def decoding(bins, xL, xR, pre):
    N = int(np.ceil(np.log2((xR-xL)/pre)))
    M = int(len(bins)/N)
    return [decodeOne(bins[N*i:N*(i+1)], xL, pre, N) 
        for i in range(M)]

其中,codeOne用于编码单个变量,coding可编码多个变量。其中输入参数xL, xR, pre的数据格式可以改写为列表,从而使得待求解参数更加灵活。

遗传

遗传就是基因的复制和交叉,有的时候可能还会发生一点突变,其中交叉过程相对复杂,故而封装成一个函数

import numpy as np
# b1,b2为编码后的二进制串
# M为编码后的二进制长度;index为自然数列
def cross(b1, b2, M, index):
    np.random.shuffle(index)
    i1 = index[:randint(0,M)]
    np.random.shuffle(index)
    i2 = index[:randint(0,M)]
    b1[i1], b2[i2] = b2[i1], b1[i2]

其中,shuffle相当于是把数组打乱,index为自然数列,当然被打乱多次后已经面目全非了。cross实现的功能是,对于输入的b1和b2,任选其中的某几位进行交换。

下面是进化过程,也就是单步执行的程序,主要包括劣种淘汰、交叉以及突变三个过程。

from copy import deepcopy
from random import randint
# rMuta为突变概率;nDie为每一代淘汰掉的个数
def genetic(xs, func, xL, xR, pre, nMuta, nDie):
    N = len(xs)
    fs = [func(x) for x in xs]
    index = np.argsort(fs)
    fBest = fs[index[0]]
    # 将最差的淘汰掉,将最优的提取出来
    xs[index[-nDie:]] = xs[index[:nDie]]
    # 编码
    bs = [coding(x, xL, xR, pre) for x in xs]
    M = len(bs[0])      # 此为编码后的参数长度
    index = np.arange(M)
    # 交叉
    for i in range(N//2):
        cross(bs[i*2], bs[i*2+1], int(M/2), index)
    # 此为突变点个数
    for b in bs:
        np.random.shuffle(index)
        b[index[:nMuta]] = ~b[index[:nMuta]]
    # 最后解码并输出
    xs = [decoding(b, xL, xR, pre) for b in bs]
    return np.array(xs), fBest

主程序

所谓主程序,就是加上一个逐代繁衍的循环

uniRand = np.random.uniform
# nId为个体数;nDim为参数维度;nIter为迭代数
# xRange为x取值范围,pre是精度
def GA(func, nId, nDim, nIter, 
    xRange, pre, rMuta, nDie):
    xs = [uniRand(*xRange, nDim) for _ in range(nId)]
    xs = np.array(xs)
    for i in range(nIter):
        xs, fBest = genetic(xs, func, xRange[0], xRange[1],
            pre, rMuta, nDie)
        if i%20==0:
            msg = f"第{i}次迭代,最佳结果为{fBest}"
            print(msg)
    fs = [func(x) for x in xs]
    index = np.argmin(fs)
    msg = "当前参数:" + ",".join([f"{x}" for x in xs[index]])
    print(msg)

测试

最后又到了激动人心的测试环节,还是用

def test(xs):
    _sum = 0.0
    for i in range(len(xs)):
        _sum = _sum + np.cos((xs[i]*i)/5)*(i+1)
    return _sum
if __name__ == "__main__":
    GA(test, 30, 5, 101, (-5,5), 1e-6, 2, 2)

得到结果为

>python GA.py
第0次迭代,最佳结果为-6.109745260005657
第20次迭代,最佳结果为-11.73854686214257
第40次迭代,最佳结果为-11.656344079309445
第60次迭代,最佳结果为-11.366187890697542
第80次迭代,最佳结果为-11.526653664416903
第100次迭代,最佳结果为-11.329056280514049
当前参数:8.073827999999999,11.655532000000001,7.032817,4.2005289999999995,-4.371395

到此这篇关于纯Python实现遗传算法详解的文章就介绍到这了,更多相关Python遗传算法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 采用python实现简单QQ单用户机器人的方法

    采用python实现简单QQ单用户机器人的方法

    这篇文章主要介绍了采用python实现简单QQ单用户机器人的方法,需要的朋友可以参考下
    2014-07-07
  • python实现多进程代码示例

    python实现多进程代码示例

    Python中大部分情况下都需要使用多进程,Python中提供了multiprocessing这个包实现多进程。multiprocessing支持子进程、进程间的同步与通信,本文就详细的介绍一下
    2018-10-10
  • Django如何将URL映射到视图

    Django如何将URL映射到视图

    这篇文章主要介绍了Django如何将URL映射到视图,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • Python基于template实现字符串替换

    Python基于template实现字符串替换

    这篇文章主要介绍了Python基于template实现字符串替换,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11
  • pytorch实现好莱坞明星识别的示例代码

    pytorch实现好莱坞明星识别的示例代码

    本文主要介绍了pytorch实现好莱坞明星识别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • python Matplotlib数据可视化(1):简单入门

    python Matplotlib数据可视化(1):简单入门

    这篇文章主要介绍了python Matplotlib的相关资料,帮助大家入门matplotlib,绘制各种图表,感兴趣的朋友可以了解下
    2020-09-09
  • Python调用GPT3.5接口的最新方法实例详解

    Python调用GPT3.5接口的最新方法实例详解

    这篇文章主要介绍了Python调用GPT3.5接口的最新方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • python图片合成的示例

    python图片合成的示例

    这篇文章主要介绍了python图片合成的示例,帮助大家更好的理解和使用python,感兴趣的朋友可以了解下
    2020-11-11
  • python将三维数组展开成二维数组的实现

    python将三维数组展开成二维数组的实现

    今天小编就为大家分享一篇python将三维数组展开成二维数组的实现,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-11-11
  • Python生成各式各样的图像特效实例

    Python生成各式各样的图像特效实例

    这篇文章主要为大家介绍了Python生成图像特效,本文重点介绍如何使用python进行图像处理,生成各式各样的图像特效,有需要的朋友可以借鉴参考下,希望能够有所帮助
    2023-10-10

最新评论