一个完全面向对象的竞争性遗传算法框架

pyrimidine的Python项目详细描述


嘧啶

遗传算法的python面向对象实现。有关详细信息,请参见pyrimidine's document。在

LOGO

为什么

为什么包装名为“嘧啶”?因为它以“py”开头。在

— Are you kiding?

— No, I am serious.

下载

它已经上传到pypi,所以用pip install pyrimidine下载,也可以从github下载。在

想法

我们把人口看作个体的容器,把个体看作染色体的容器 以及作为基因容器(阵列)的染色体。在

容器可以是列表或数组。 容器类有一个属性element_class,它告诉自己其中元素的类。在

以下是BaseIndividualBasePopulation的源代码部分。在

classBaseIndividual(BaseFitnessModel,metaclass=MetaContainer):element_class=BaseChromosomedefault_size=1classBasePopulation(BaseFitnessModel,metaclass=MetaHighContainer):element_class=BaseIndividualdefault_size=20

容器主要有两种:列表和元组,如编程语言Haskell。参见以下示例。在

^{pr2}$

使用

主要类别

  • 基基因:染色体的基因
  • 基本染色体:基因序列,代表解决方案的一部分
  • 基本个体:染色体序列,代表一个问题的解决方案
  • 一组个体,代表一组问题 也就是不稳定的过程
  • 基种:更复杂优化的种群集合

导入

只需使用命令from pyrimidine import *导入所有对象。在

子类

染色体

一般来说,它是一组基因。在

作为0-1的数组,BinaryChromosome最常用。在

个人

在大多数情况下,只是子类MonoIndividual。在

classMyIndividual(MonoIndividual):"""individual with only one chromosome    we set the gene is 0 or 1 in the chromosome    """element_class=BinaryChromosomedef_fitness(self):...

由于类MonoBinaryIndividual被定义为这样的个体,它等价于

classMyIndividual(MonoBinaryIndividual):# only need define the fitnessdef_fitness(self):...

如果一个个体包含几个染色体,那么子类MultiIndividual。它可以应用于多实变量优化问题。在

在大多数情况下,我们必须将染色体解码为实数。在

class_Chromosome(BinaryChromosome):defdecode(self):"""Decode a binary chromosome        if the sequence of 0-1 represents a real number, then overide the method        to transform it to a nubmer        """classExampleIndividual(BaseIndividual):element_class=_Chromosomedef_fitness(self):# define the method to calculate the fitnessx=self.decode()# will call decode method of _Chromosomereturnevaluate(x)

如果个体中的染色体彼此不同,那么子类MixIndividual,同时,属性{}应该为每个染色体分配一个类元组。在

classMyIndividual(MixIndividual):"""    Inherit the fitness from ExampleIndividual directly.    It has 6 chromosomes, 5 are instances of _Chromosome, 1 is instance of FloatChromosome    """element_class=(_Chromosome,)*5+(FloatChromosome,)

它相当于MyIndividual=MixIndividual[(_Chromosome,)*5 + (FloatChromosome,)]

人口
classMyPopulation(SGAPopulation):element_class=MyIndividual

element_class是类的最重要属性,它定义了群体中个体的类。它相当于MyPopulation=SGAPopulation[MyIndividual]。在

随机初始化

初始化填充

产生一个群体,有50个个体,每个个体有100个基因

pop = MyPopulation.random(n_individuals=50, size=100)

当每个个体包含5条染色体时。在

pop = MyPopulation.random(n_individuals=10, n_chromosomes=5, size=10)

对于MixIndividual,我们建议使用,例如

pop = MyPopulation.random(n_individuals=10, sizes=(10,8,8,3))

初始化个人

实际上,Populationrandom方法将调用Individual的随机方法。如果您想生成一个个体,那么只需执行MyIndividual.random(n_chromosomes=5, size=10),对于简单的个体,只需执行SimpleIndividual.random(size=10),因为它的n_chromosomes等于1。在

进化

evolve方法

使用random方法初始化填充,然后调用evolve方法。在

pop=MyPopulation.random(n_individuals=50,size=100)pop.evolve()print(pop.best_individual)

设置verbose=True以显示每一代的数据。在

历史

了解进化史。在

stat={'Fitness':'fitness','Best Fitness':lambdapop:pop.best_individual.fitness}data=pop.history(stat=stat)# use history instead of evolve

stat是一个dict映射键到函数的dict,其中字符串'fitness'表示函数lambda pop:pop.fitness,它获得pop的平均适应度。因为我们已经定义流行音乐最佳个人音乐.fitness作为属性,stat可以重新定义为{'Fitness':'fitness', 'Best Fitness': 'best_fitness'}。在

性能

使用pop.perf()检查性能。在

示例

例1

说明

select ti, ni from t, n
sum of ni ~ 10, while ti dose not repeat

选择。问题是

min abs(sum_i{ni}-10) + maximum of frequences in {ti}
where i is selected.
t=np.random.randint(1,5,100)n=np.random.randint(1,4,100)importcollectionsdefmax_repeat(x):# maximum of numbers of repeatsc=collections.Counter(x)bm=np.argmax([bfora,binc.items()])returnlist(c.keys())[bm]classMyIndividual(BinaryIndividual):def_fitness(self):x,y=self.evaluate()return-x-ydefevaluate(self):returnabs(np.dot(n,self.chromosome)-10),max_repeat(tiforti,cinzip(t,self)ifc==1)classMyPopulation(SGAPopulation):element_class=MyIndividualpop=MyPopulation.random(n_individuals=50,size=100)pop.evolve()print(pop.best_individual)

注意到MonoIndividual中只有一条染色体,可以通过self.chromosome获得。在

例2:背包问题

其中一个著名的问题是背包问题。这是遗传算法的一个很好的例子

我们在evolve方法中设置history=True,它将记录whol的主要数据进化论。它将返回一个pandas.DataFrame的对象。参数stat是一个dict,它从一个key到function/str(对应于一个方法)映射一个总体到一个数字。一代中的数字将存储在数据帧的一行中。在

# examples/example0

#!/usr/bin/env python3# -*- coding: utf-8 -*-frompyrimidineimportMonoBinaryIndividual,SGAPopulationfrompyrimidine.benchmarks.optimizationimport*# generate a knapsack problem randomlyevaluate=Knapsack.random(n=20)classMyIndividual(MonoBinaryIndividual):def_fitness(self):returnevaluate(self)classMyPopulation(SGAPopulation):element_class=MyIndividualpop=MyPopulation.random(size=20)stat={'Mean Fitness':'mean_fitness','Best Fitness':'best_fitness'}data=pop.evolve(stat=stat,history=True)# data is an instance of DataFrame of pandasimportmatplotlib.pyplotaspltfig=plt.figure()ax=fig.add_subplot(111)data[['Mean Fitness','Best Fitness']].plot(ax=ax)ax.set_xlabel('Generations')ax.set_ylabel('Fitness')plt.show()

plot-history

扩展

pyrimidine是可扩展的。它易于实现其他迭代模型,如模拟退火和粒子群优化。在

目前,建议将基于BaseIterativeModel的子类定义为maxin。在

在粒子群优化算法中,我们把粒子看作一个个体,ParticleSwarm作为一个总体。但是在下面,我们将它从BaseIterativeModel子类化

# pso.pyclassParticle(PolyIndividual):"""A particle in PSO    Variables:        default_size {number} -- one individual represented by 2 chromosomes: position and velocity        phantom {Particle} -- the current state of the particle moving in the solution space.    """element_class=FloatChromosomedefault_size=2phantom=Nonedefbackup(self):self.chromosomes[0]=self.positionself.fitness=self.phantom.fitnessdefinit(self):self.phantom=self.clone(fitness=self.fitness)# other methodsclassParticleSwarm(BaseIterativeModel):element_class=Particledefault_size=20params={'learning_factor':2,'acceleration_coefficient':3,'inertia':0.5,'n_best_particles':0.1,'max_velocity':None}definit(self):self.best_particles=self.get_best_individuals(self.n_best_particles)forparticleinself.particles:particle.init()deftransit(self,*args,**kwargs):"""        Transitation of the states of particles        """forparticleinself:ifparticle.phantom.fitness>particle.fitness:particle.backup()forparticleinself:ifparticlenotinself.best_particles:fork,binenumerate(self.best_particles):ifparticle.fitness<=b.fitness:breakifk>0:self.best_particles.pop(k)self.best_particles.insert(k,particle)self.move()defmove(self):# moving rule of particlesxi=random()eta=random()forparticleinself:ifparticleinself.best_particles:particle.velocity=(self.inertia*particle.velocity+self.learning_factor*xi*(particle.best_position-particle.position))else:forbinself.best_particles:ifparticle.fitness<b.fitness:breakparticle.velocity=(self.inertia*particle.velocity+self.learning_factor*xi*(particle.best_position-particle.position)+self.acceleration_coefficient*eta*(b.best_position-particle.position))particle.position+=particle.velocityparticle.phantom.fitness=None

如果您想应用PSO,那么您可以定义

classMyParticleSwarm(ParticleSwarm,BasePopulation):element_class=_Particledefault_size=20pop=MyParticleSwarm.random()

这不是强迫性的。可以直接从BasePopulation继承{}。在

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
在Eclipse中使用多个调用在一行上打印java   javajackson序列化问题。只有同一实体的第一个对象可以很好地序列化   Java中Deflate函数的等价充气   使用customlitview的java Android actionbar搜索   java“<T>T get()”是什么意思?(它有用吗?)   目标c使用CommonCrypto使用AES256加密,使用OpenSSL或Java解密   java在运行时更新资源文件   fileinputstream在java中访问并将数据写入现有文件   带集群的java Android Mapbox我希望每个功能都有不同的标记图像   java JDK8>JDK10:PKIX路径生成失败:SunCertPathBuilderException:找不到请求目标的有效证书路径   java使用Hk2生成具有指定构造函数参数的实例   为什么这个系统。出来Java中的println()打印到控制台?   java目录和文件名连接不起作用   使用mockito和通配符绘图的java