GAFT:一个使用Python实现的遗传算法框架
專 欄
❈PytLab,Python 中文社区专栏作者。主要从事科学计算与高性能计算领域的应用,主要语言为Python,C,C++。熟悉数值算法(最优化方法,蒙特卡洛算法等)与并行化 算法(MPI,OpenMP等多线程以及多进程并行化)以及python优化方法,经常使用C++给python写扩展。
知乎专栏:化学狗码砖的日常
blog:http://pytlab.org
github:https://github.com/PytLab
❈
前言
最近需要用到遗传算法来优化一些东西,最初是打算直接基于某些算法实现一个简单的函数来优化,但是感觉单纯写个非通用的函数运行后期改进算子或者别人使用起来都会带来困难,同时遗传算法基本概念和运行流程相对固定,改进也一般通过编码机制,选择策略,交叉变异算子以及参数设计等方面,对于算法的整体结构并没有大的影响。这样对于遗传算法来说,就非常适合写个相对固定的框架然后给算子、参数等留出空间以便对新算法进行测试和改进。于是就动手写了个遗传算法的小框架gaft,本文对此框架进行一些介绍并分别以一个一维搜索和二维搜索为例子对使用方法进行了介绍。
目前框架只是完成了最初的版本,比较简陋,内置了几个基本的常用算子,使用者可以根据接口规则实现自定义的算子并放入框架中运行。我自己也会根据自己的需求后续添加更多的改进算子,同时改进框架使其更加通用.
正文
遗传算法介绍
这里我对遗传算法的基本概念进行简要的介绍,并阐述gaft的设计原则。
简单而言,遗传算法使用群体搜索技术,将种群代表一组问题的可行解,通过对当前种群施加选择,交叉,变异等一些列遗传操作来产生新一代的种群,并逐步是种群进化到包含近似全局最优解的状态。下面我将遗传学和遗传算法相关术语的对应关系总结一下:
术语
算法特点
1、以决策变量的编码作为运算对象,使得优化过程借鉴生物学中的概念成为可能 2、直接以目标函数作为搜索信息,确定搜索方向很范围,属于无导数优化 3、同时使用多个搜索点的搜索信息,算是一种隐含的并行性 4、是一种基于概率的搜索技术 5、具有自组织,自适应和自学习等特性
算法流程
gaft 设计原则
由于遗传算法的流程相对固定,我们优化算法基本上也是在流程整体框架下对编码机制,算子,参数等进行修改,因此在写框架的时候,我便想把那些固定的遗传算子,适应度函数写成接口,并使用元类、装饰器等方式实现对接口的限制和优化,这样便可以方便后续自定义算符和适应度函数定制。最后将各个部分组合到一起组成一个engine然后根据算法流程运行遗传算法对目标进行优化.
这样我们便脱离每次都要写遗传算法流程的繁琐,每次只需要像写插件一样实现自己的算子和适应度函数便可以将其放入gaft开始对算法进行测试或者对目标函数进行优化了。
GAFT文件结构
此部分我对自己实现的框架的整体结构进行下介绍.
目前的文件结果如上所示,
- /gaft/components中定义了内置的个体和种群类型,提供了两种不同的遗传编码方式:二进制编码和实数编码。
- /gaft/plugin_interfaces中是插件接口定义,所有的算子定义以及on-the-fly分析的接口规则都在里面,使用者可以根据此来编写自己的插件并放入到engine中。
- /gaft/operators里面是内置遗传算子,他们也是遵循/gaft/plugin_interfaces中的规则进行编写,可以作为编写算子的例子。其中算子我目前内置了roulette wheel选择算子,uniform 交叉算子和flipbit变异算子,使用者可以直接使用内置算子来使用gaft对自己的问题进行优化。
- /gaft/analysis里面是内置的on-the-fly分析插件,他可以在遗传算法迭代的过程中对迭代过程中的变量进行分析,例如我在里面内置了控制台日志信息输出,以及迭代适应度值的保存等插件方便对进化曲线作图。
- /gaft/engine便是遗传算法的流程控制模块了,他将所有的之前定义的各个部分组合到一起使用遗传算法流程进行优化迭代。
使用GAFT
下面我就以两个函数作为例子来使用GAFT对目标函数进行优化.
一维搜索
首先我们先对一个简单的具有多个局部极值的函数进行优化,我们来使用内置的算子求函数
的极大值,x的取值范围为[0,10]
1. 先导入需要的模块
2. 创建引擎
3. 自定义适应度函数
可以通过修饰符的方式将,适应度函数注册到引擎中。
4. 自定义on-the-fly分析插件
也可以通过修饰符在定义的时候直接将插件注册到引擎中
5. Ok, 开始跑(优化)吧!
我们这里跑100代种群.
内置的分析插件会在每步迭代中记录得到的每一代的最优个体,并生成数据保存。
绘制一下函数本身的曲线和我们使用遗传算法得到的进化曲线:
优化过程动画:
二维搜索
下面我们使用GAFT内置算子来搜索同样具有多个极值点的二元函数
的最大值,x, y 的范围为 [−2,2].
这里我们就不自定义分析插件了,直接使用内置的分析类,并在构造引擎时直接传入.
进化曲线:
二维函数面:
搜索过程动画:
可见目前内置的基本算子都能很好的找到例子中函数的最优点。
总结
本文主要介绍了本人开发的一个用于遗传算法做优化计算的Python框架,框架内置了遗传算法中常用的组件,包括不同编码方式的个体,种群,以及遗传算子等。同时框架还提供了自定义遗传算子和分析插件的接口,能够方便快速搭建遗传算法流程并用于算法测试。
目前框架仅仅处于初步阶段,后续会在自己使用的过程中逐步完善更多的内置算子,是框架更加通用。本文中的两个优化例子均能在GitHub上找到源码(https://github.com/PytLab/gaft/tree/master/examples)
目前的计划:1. 添加更多的内置算子; 2. 给内置算子和组件添加C++ backend; 3. 并行化
参考
《智能优化算法及其MATLAB实例》
《MATLAB最优化计算》
- 携程React Native实践
- 数据分析告诉你:Php最不安全,Nginx比Apache安全
- 用python抓取摩拜单车API数据并做可视化分析(源码)
- 用Pandas在Python中可视化机器学习数据
- Intent 属性详解(下)
- 把复杂json解析成javabean思路:思路:
- Python数据科学计算库的安装和numpy简单
- 4G安全:研究人员发现攻击4G无线上网卡和SIM卡的方法
- Python文学化编程 - Jupyter notebook使用和插件拓展
- PoisonCake(毒蛋糕):内置于手机ROM的恶意代码模块
- Spring+SpringMVC+MyBatis整合
- Python之numpy数组学习(五)——广播
- WordPress再悲剧:WPcache-Blogger感染事件影响五万WordPress网站
- 浅谈神经机器翻译
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- springboot 默认日志配置源码
- logback 通过javaconfig实现配置
- springboot通过javaconfig实现logback配置
- 干货来了,vue 3.0 自定义指令变化
- XXE注入漏洞
- vue + typescript 类组件教程
- 图像处理笔记(3)----OpenCV图像算术运算
- V - Distpicker 是一个简单易用的地区选择器
- [漫谈] 状态
- 变量覆盖
- 【Rust日报】2020-08-27 在Arduino Uno上面跑 Rust 程序
- 浅谈类加载
- Rust FFI 编程 - Rust导出共享库06
- go语言文件操作汇总
- Redis 主从复制 哨兵模式实战