专栏首页Python中文社区使用MPI for Python 并行化遗传算法

使用MPI for Python 并行化遗传算法

專 欄

❈PytLab,Python 中文社区专栏作者。主要从事科学计算与高性能计算领域的应用,主要语言为Python,C,C++。熟悉数值算法(最优化方法,蒙特卡洛算法等)与并行化 算法(MPI,OpenMP等多线程以及多进程并行化)以及python优化方法,经常使用C++给python写扩展。

blog:http://ipytlab.com

github:https://github.com/PytLab

前言

本文中作者使用MPI的Python接口mpi4py来将自己的遗传算法框架GAFT进行多进程并行加速。并对加速效果进行了简单测试。

项目链接:

正文

我们在用遗传算法优化目标函数的时候,函数通常都是高维函数,其导数一般比较难求取。这样我们的适应度函数计算通常都是比较费时的计算。

例如在使用遗传算法寻找最优结构时候通常需要调用量化软件进行第一性原理计算结构的total energy,这是非常费时的过程; 例如我们优化力场参数的时候,以力场计算出的能量同基准能量之前的误差作为适应度,也需要调用相应的力场程序获取总能量来求取,同样这个过程也是相对耗时的。

这就会导致一个问题,当我们的种群比较大的时候,我们需要利用适应度信息来产生下一代种群,这时候每一代繁殖的过程将会很耗时。但有幸的是,种群的选择交叉变异过程对于种群中的个体都是相互独立的过程,我们可以将这一部分进行并行处理来加速遗传算法的迭代。

使用mpi4py

由于实验室的集群都是MPI环境,我还是选择使用MPI接口来将代码并行化,这里我还是用了MPI接口的Python版本mpi4py来将代码并行化。关于mpi4py的使用,我之前写过一篇博客专门做了介绍,可以参见《Python多进程并行编程实践-mpi4py的使用》

将mpi4py的接口进一步封装

为了能让mpi的接口在GAFT中更方便的调用,我决定将mpi4py针对遗传算法中需要用的地方进行进一步封装,为此我单独写了个MPIUtil类, 详细代码参见gaft/mpiutil.py。

封装通信子常用的接口

例如进程同步, 获取rank,进程数,判断是否为主进程等。

组内集合通信接口

由于本次并行化的任务是在种群繁衍时候进行的,因此我需要将上一代种群进行划分,划分成多个子部分,然后在每个进程中对划分好的子部分进行选择交叉变异等遗传操作。在最后将每个字部分得到的子种群进行收集合并。为此写了几个划分和收集的接口:

用于限制程序在主进程执行的装饰器

有些函数例如日志输出,数据收集的函数,我只希望在主进程执行,为了方便,写了个装饰器来限制函数在主进程中执行:

在遗传算法主循环中添加并行

主要在种群繁衍中对种群针对进程数进行划分然后并行进行遗传操作并合并子种群完成并行,代码改动很少。详见:https://github.com/PytLab/gaft/blob/master/gaft/engine.py#L67

测试加速效果 测试一维搜索

下面我针对项目中的一维优化的例子进行并行加速测试来看看加速的效果。例子代码在/examples/ex01/

由于自己本子核心数量有限,我把gaft安装在实验室集群上使用MPI利用多核心进行并行计算一维优化,种群大小为50,代数为100代,针对不同核心数可以得到不同的优化时间和加速比。可视化如下图:

核心数与优化时间的关系:

核心数与加速比:

测试力场优化

这里我对自己要研究的对象进行加速测试,这部分代码并未开源,针对每个个体的适应度计算都需要调用其他的计算程序,因此此过程相比直接有函数表达式的目标函数计算要耗时很多。

同样,我针对不同核心数看看使用MPI在集群上加速的效果:

核心数与优化时间的关系:

核心数与加速比:

可见针对上述两个案例,MPI对遗传算法的加速还是比较理想的,程序可以扔到集群上飞起啦~~~

总结

本文主要总结了使用mpi4py对遗传算法进行并行化的方法和过程,并对加速效果进行了测试,可见MPI对于遗传算法框架GAFT的加速效果还是较为理想的。带有MPI并行的遗传算法框架目前也已更新并上传至GitHub(https://github.com/PytLab/gaft) 欢迎围观

本文分享自微信公众号 - Python中文社区(python-china),作者:PytLab

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-08-30

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • OpenStack中的RESTful API是如何实现的?

    OpenStack作为一个开源的IaaS平台,各个组件和服务之间的消息传递都是通过RESTfulAPI和RPC传递,这里主要讲讲它是如何实现REST的。由于大家...

    Python中文社区
  • 协同过滤的原理及Python实现

    作者:李小文,先后从事过数据分析、数据挖掘工作,主要开发语言是Python,现任一家小型互联网公司的算法工程师。

    Python中文社区
  • GBDT回归的原理及Python实现

    提到GBDT回归相信大家应该都不会觉得陌生,本文就GBDT回归的基本原理进行讲解,并手把手、肩并肩地带您实现这一算法。完整实现代码请参考本人的github。

    Python中文社区
  • JDK8新特性之接口默认方法与静态方法

    接口默认方法与静态方法 有这样一些场景,如果一个接口要添加一个方法,那所有的接口实现类都要去实现,而某些实现类根本就不需要实现这个方法也要写一个空实现,所以接口...

    Java技术栈
  • T-GCN:时间图卷积网络用于交通速度预测-模型实验部分

    《T-GCN: A Temporal Graph Convolutional Network for Traffic Prediction》。

    深度学习与交通大数据
  • 游戏版本更新小记

    先大概介绍一下项目,卡牌游戏,主要面向女性用户。前期是走IOS市场,后来又移值到Android平台上,在几家大一点的Android渠道上进行运营。Android...

    meteoric
  • 资讯 | 携程首度引入VR技术,攻略社区将全面升级

    近日携程攻略客户端2.4正式上线Apple Store和各大安卓市场,新版本突破性地引入了VR游记功能,用户通过携程攻略客户端即可预览VR场景。 此外,用户可以...

    携程技术
  • namp 渗透测试-安装篇

    nmap是一个网络连接端扫描软件,用来扫描网上电脑开放的网络连接端。确定哪些服务运行在哪些连接端,并且推断计算机运行哪个操作系统。

    致码DevOps
  • TOKIO ASYNC&AWAIT 初探

    rust的async/await终于在万众瞩目之下稳定下来了,一起来尝尝鲜. 这篇文章主要是介绍基于tokio 0.2做一个服务程序员的小工具githubdns...

    MikeLoveRust
  • LeetCode117:填充每个节点的下一个右侧节点指针 II

    填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。

    爱写bug

扫码关注云+社区

领取腾讯云代金券