当前位置: 首页 > 科技观察

GAFT-AGeneticAlgorithmFrameworkImplementedinPython_0

时间:2023-03-19 20:20:29 科技观察

前言最近需要用遗传算法优化一些东西。一开始打算实现一个简单的函数,直接基于某种算法进行优化,但是感觉自己简单的写一个非通用的函数,在后期运行或者给别人使用的时候改进算子,会带来困难。同时,遗传算法的基本概念和运行过程相对固定,一般通过编码机制、选择策略、交叉变异算子、参数设计等进行改进。对于算法的整体结构没有太大的影响。这样,对于遗传算法来说,很适合写一个相对固定的框架,给算子、参数等留有余地来测试和改进新的算法。于是自己写了一个遗传算法的小框架gaft。本文介绍该框架,并以一维搜索和二维搜索为例介绍使用方法。GitHub:https://github.com/PytLab/gaftPyPI:https://pypi.python.org/pypi/gaft目前框架只完成了初始版本,比较简单,内置了几个基本的常用算子.用户可以根据接口规则实现自定义算子,放到框架中运行。我也会根据自己的需要加入更多改进的算子,完善框架,让它更通用。遗传算法简介这里简单介绍遗传算法的基本概念,并说明GAFT的设计原则。简单来说,遗传算法是利用种群搜索技术,将种群表示为一组问题的可行解,对当前种群进行选择、交叉、变异等一系列遗传操作,生成新一代种群。population,并逐步演化population以包含近似全局解的状态。下面我总结一下遗传学和遗传算法相关术语的对应关系:术语和算法特点:以决策变量的编码为操作对象,使得优化过程可以借鉴生物学中的概念,直接使用目标函数作为确定搜索方向的搜索信息,属于无导数优化的范畴,同时使用多个搜索点的搜索信息,可以看作是一种隐含的并行性。它是一种基于概率的搜索技术,具有自组织、自适应和自学习的特点。算法流程gaft的设计原则是由于遗传算法的流程相对固定。我们的优化算法基本上就是在流程的整体框架下修改编码机制、算子、参数等。因此,在写框架的时候,我想把那些固定的遗传算子、适应度函数写成接口,通过元类、装饰器等来对接口进行约束和优化,以便后续定制自定义算子和适应度函数。得到便利。***将各个部分组合在一起形成一个引擎,然后根据算法流程运行遗传算法优化目标。这样我们就摆脱了每次都写遗传算法过程的繁琐,每次只需要像写插件一样实现自己的算子和适应度函数,放到gaft中就可以开始测试算法了或者优化目标函数。GAFT文件结构这部分我会介绍一下我实现的框架的整体结构。├──gaft│├──__init__.py│├──__pycache__│├──分析│├──组件│├──engine.py│├──operators│└──plugin_interfaces├──setup.cfg├──setup.py└──tests├──flip_bit_mutation_test.py├──gaft_test.py├──individual_test.py├──population_test.py├──roulette_wheel_selection_test.py└──uniform_crossover_test.py当前文件结果为如上所示,在/gaft/components中定义了内置的个体和种群类型,并提供了两种不同的遗传编码方式:二进制编码和真实编码。/gaft/plugin_interfaces是插件接口定义,所有算子定义和动态分析接口规则都在里面,用户可以以此为基础编写自己的插件放入引擎中。/gaft/operators中内置了遗传算子,也是按照/gaft/plugin_interfaces中的规则编写的,可以作为编写算子的例子。在算子中,我目前内置了轮盘赌选择算子、均匀交叉算子和flipbit变异算子。用户可以直接使用内置的算子使用gaft优化自己的问题。/gaft/analysis包含内置的on-the-fly分析插件,可以在遗传算法迭代过程中分析迭代过程中的变量。比如我内置了控制台日志信息输出和迭代适应度值保存等插件,方便绘制进化曲线。/gaft/engine是遗传算法的过程控制模块,它将之前定义的所有部分组合在一起,使用遗传算法过程进行优化迭代。UsingGAFTNext,IwillusetwofunctionsasexamplestooptimizetheobjectivefunctionusingGAFT.One-dimensionalsearchFirst,wefirstoptimizeasimplefunctionwithmultiplelocalextrema,andweusethebuilt-inoperatortofindthefunctionThemaximumvalueoff(x)=x+10sin(5x)+7cos(4x),thevaluerangeofxis[0,10]1.Firstimporttherequiredmodulefrommathimportsin,cos#Importpopulationisrelatedtothebuilt-inoperator类fromgaftimportGAEnginefromgaft.componentsimportGAIndividualfromgaft.componentsimportGAPopulationfromgaft.operatorsimportRouletteWheelSelectionfromgaft.operatorsimportUniformCrossoverfromgaft.operatorsimportFlipBitMutation#用于编写分析插件的接口类fromgaft.plugin_interfaces.analysisimportOnTheFlyAnalysis#内置的存档适应度函数的分析类fromgaft.analysis.fitness_storeimportFitnessStoreAnalysis#我们将用两种方式将分析Registertheplug-intothegeneticalgorithmengine2.Createtheengine#Definethepopulationindv_template=GAIndividual(ranges=[(0,10)],encoding='binary',eps=0.001)population=GAPopulation(indv_template=indv_template,size=50)#Createageneticoperatorselection=RouletteWheelSelection()crossover=UniformCrossover(pc=0.8,pe=0.5)mutation=FlipBitMutation(pm=0.1)#Createageneticalgorithmengine,analysisplug-insandfitnessfunctionscanbepassedintotheengineasparametersEngine=GAEngine(population=population,selection=selection,crossover=crossover,mutation=mutation,analysis=[FitnessStoreAnalysis])3.自定义适应度函数可以通过修饰符@engine.fitness_registerdeffitness(indv):x,=indv.variantsreturnx+10*sin(5*x)+7*cos(4*x)4注册到引擎中。自定义on-the-fly分析插件也可以直接通过修饰符将插件注册到引擎@engine.analysis_registerclassConsoleOutputAnalysis(OnTheFlyAnalysis):interval=1defregister_step(self,ng,population,engine):best_indv=population.best_indv(engine.fitness)msg='Generation:{},bestfitness:{:.3f}'.format(ng,engine.fitness(best_indv))engine.logger.info(msg)deffinalize(self,population,engine):best_indv=population.best_indv(engine.fitness)x=best_indv.variantsy=engine.fitness(best_indv)msg='Optimalsolution:({},{})'.format(x,y)engine.logger.info(msg)5.好的,让我们运行(优化)!我们在这里运行100代人口。if'__main__'==__name__:#RuntheGAengine.engine.run(ng=100)内置分析插件会在每次迭代中记录每代获得的***个个体,并生成数据保存。画出函数本身的曲线和利用遗传算法得到的演化曲线:优化过程动画:二维搜索接下来我们使用GAFT内置的算子搜索二元函数f(x)=ysin(2πx)+xcos(2πy),x,y的取值范围为[?2,2]。这里我们不自定义分析插件,直接使用内置的分析类,直接通过Import'''Findtheglobalmaximumforbinaryfunction:f(x)=y*sim(2*pi*x)+x*cos(2*pi*y)'''frommathimportsin,cos,pifromgaftimportGAEnginefromgaft.componentsimportGAIndividualfromgaft.componentsimportGAPopulationfromgaftUni.operatorsimportRooperetteWheelfromgaftfromgaft.componentsimportGAPopulationfromgaftUni.operatorsimportRooperetteWheelfromgaftfromgaft.componentsimportoperatorsimportFlipBitMutation#Built-inbestfitnessanalysis.fromgaft.analysis.fitness_storeimportFitnessStoreAnalysisfromgaft.analysis.console_outputimportConsoleOutputAnalysis#Definepopulation.indv_template=GAIndividual(范围=[(-2,2),(-2,0=eps1).binary',encopopulation=GAPopulation(indv_template=indv_template,size=50)#Creategeneticoperators.selection=RouletteWheelSelection()crossover=UniformCrossover(pc=0.8,pe=0.5)mutation=FlipBitMutation(pm=0.1)#Creategeneticalgorithmengine.#Herewe将所有内置分析传递给引擎constructor.engine=GAEngine(population=population,selection=selection,crossover=crossover,mutation=mutation,analysis=[ConsoleOutputAnalysis,FitnessStoreAnalysis])#Definefitnessfunction.@engine.fitness_registerdeffitness(indv):x,y=indv*sin(2*pi*x)+x*cos(2*pi*y)if'__main__'==__name__:engine.run(ng=100)演化曲线:二维函数面:搜索过程动画:目前可见内置的基本运算符可以很好的找到例子中函数的关键点。总结本文主要介绍本人开发的一个用于遗传算法优化计算的Python框架。该框架内置了遗传算法中常用的组件,包括具有不同编码方式的个体、种群和遗传算子。同时,该框架还提供了自定义遗传算子和分析插件的接口,可以方便快捷地构建遗传算法流程并用于算法测试。目前该框架还处于初级阶段,未来在自身使用的过程中会逐步完善更多的内置算子,使框架更加通用。本文中两个优化示例的源代码可以在GitHub上找到(https://github.com/PytLab/gaft/tree/master/examples)。目前计划:1.增加更多内置算子;2.给内置算子和组件添加C++后端;3.并行化参考《智能优化算法及其MATLAB实例》《MATLAB***化计算》