DEAP 框架笔记
文章目录
- DEAP 框架笔记
- 使用creator模块
- 创建Fitness类
- 定义fitness策略
- 存储fitness值
- 创建Individual类
- 使用Toolbox类
- 创建遗传算子
- 创建种群
- 创建fitness
DEAP(Distributed Evolutionary Algorithms in Python)为Python框架,支持采用遗传算法或其他演化算法进行快速求解。
使用creator模块
creator模块通过对现有类赋予新的属性来进行扩展类。
例如,假设我们有一个类名为Employee。那么,使用creator工具,我们可以通过创建Developer类来扩展Employee类,代码如下:
from deap import creator
creator.create("Developer", Employee, position = "Developer",
programmingLanguages = set)
传递给create()函数的第一个变量为所设计的新类的名称。第二个变量为所需扩展的已有的类。然后,每个额外的变量定义新类的属性。如果变量是赋值类(例如,dict或set),那会在新类的constructor中初始化属性。如果变量不是一个类(例如,文字),则被加入作为类(static)属性。
因此,上述设置等同于如下代码:
class Developer(Employee):
position = "Developer"
def __init__(self):
self.programmingLanguages = set()
注意:新创建的类存在于creator模块中,因此需要引用为creator.Developer。
当使用DEAP时,creator模块通常被用于创建遗传算法中的Fitness类和Individual类。
创建Fitness类
当使用DEAP时,fitness值封装在Fitness类中。DAEP可以使fitness组合几种分量(或称为objective),每个分量有自己的权重。组合这些权重定义了给定问题的fitness的行为或策略。
定义fitness策略
为了定义这种策略,DEAP有抽象类base.Fitness,其包含weights元组。为了定义策略和使该类可用,需对weights元组进行赋值。这可以通过使用creator来扩展Fitness类,类似于前面Developer类:
creator.create("FitnessMax", base.Fitness, weights=(1.0,))
这样,通过扩展base.Fitness类,得到了具有weights类属性初始值为(1.0,)的creator.FitnessMax类。
注意:当只有单个权重被定义时,weights定义中的尾部的逗号是需要的,这是因为weights是元组。
FitnessMax的这种策略是使在遗传算法中的单个目标解的fitness值最大化。相反地,如果我们有单目标问题需要使fitness值最小化来求解,我们可以使用如下创建合理地最小化策略:
creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
我们也可以定义多目标优化,且每个目标地重要程度不同地策略的类:
creator.create("FitnessCompound", base.Fitness, weights=(1.0, 0.2, -0.5))
这样,我们得到了具有3个不同fitness分量的creator.FitnessCompound类。3个分量的权重分别为:1.0,0.2,-0.5.最大化第一二个分量,最小化第三个分量。其重要性的排序为:第一个、第三个和第二个。
存储fitness值
当weights元组定义了fitness策略之后,在base.Fitness类中与之相匹配的元组values,被用于包含实际fitness值。这些值由单独定义的函数来求得,一般称为evaluate()。类似于weights元组,values元组包含每个fitness分量的值。
第3个元组,wvalues,包含values元组中的每个分量于weights元组中对应分量相乘后的加权值。当一个实例定义了fitness值之后,加权值将被计算并插入到wvalues中。并且具有可以比较各自相互的大小。
一旦Fitness类创建后,我们可以在Individual类的定义中使用。
创建Individual类
creator工具的第二个常用的用途,用来定义构成遗传算法中的种群的个体。遗传算法中的个体是采用染色体表示,并能用遗传算子来操作。在DEAP中,Individual类是通过扩展表示染色体的基类来创建的。另外,DEAP中的每个个体属性中需包含fitness函数作为其中一个属性。
为了实现这两个要求,我们使用creator来创建creator.Individual类,具体如下:
creator.create("Individual", list, fitness=creator.FitnessMax)
这条代码给出了以下两种效果:
- 扩展Python的list类来创建Individual类,这意味着染色体使用的是list类型。
- Individual类的每个属性将含有fitness属性(先前创建的FitnessMax类)。
使用Toolbox类
DEAP框架提供的第二个机制为base.Toolbox类。Toolbox被用作函数(或算子)的容器,使得我们可以通过对现有函数进行别名或定制化来创建新的算子。
例如,假设我们有函数sumOfTwo(),定义如下
def sumOfTwo(a, b):
return a + b
使用toolbox,我们可以创建新的算子,incrementByFive(),这是通过定制化了sumOfTwo()函数得到的
from deap import base
toolbox= base.Toolbox()
toolbox.register("incrementByFive", sumOfTwo, b=5)
传入到register()工具箱函数的第一个参数为新算子的名字。第二个参数为需要定制化的已有的函数。然后,每个额外的参数自动传递给定制化的函数。例如,如下的定义
toolbox.incrementByFive(10)
这等同于应用先前的函数
sumOfTwo(10, 5)
这是因为参数b已经在定义incrementByFive算子时已经固定为5.
创建遗传算子
在许多情形下,Toolbox类被用于定制化tools模块内已有的函数。tools模块包含大量有关遗传算子的函数:选择、交叉和突变,以及初始化工具。
例如,如下代码定义了3个别名后续用作遗传算子
from deap import tools
toolbox.register("select", tools.selTournament, tournsize=3)
toolbox.register("mate", tools.cxTwoPoint)
toolbox.register("mutate", tools.mutFlipBit, indpb=0.02)
这3个别名的定义细节如下:
- select登记为已有tools函数selTournament()的别名,其中tournsize参数设置为3.这设置了toolbox.select算子,用来实现tournament尺寸为3的tournament选择。
- mate登记为已有tools函数cxTwoPoint()的别名。这个定义的结果为toolbox.mate算子实现两点交叉的操作。
- mutate登记为已有tools函数mutFlipBit的别名,其中indpb参数设置为0.02,给出toolbox.mutate算子用来实现翻转位突变(flip bit mutation),每个需被翻转的属性的翻转概率为0.02.
tools模块提供了各自遗传算子。
选择相关函数可以在selection.py中找到,杂交相关函数在crossover.py中,突变相关函数在mutation.py中
创建种群
tools模块的init.py文件中包含几种函数,可以用于遗传算法的种群的创建和初始化。其中一个特别有用的函数为initRepeat(),其接受3个参数:
- 容器类型,用于放置结果对象
- 函数,用于生成对象,并放置于容器
- 对象数量
例如,下面一行代码是产生30个0-1之间的随机数的列表list:
randomList = tools.initRepeat(list, random.random, 30)
在这个例子中,list作为一种需要被填充的容器,random.random为生成函数,30为应用这个生成函数的次数,产生的值用来填充容器。
如果我们想用0或1的随机整数来填充list呢?我们可以创建一个函数使用生成单个随机数0或1
的random.radint(),然后将其置于生成函数initRepeat(),代码如下:
def zeroOrOne():
return random.randint(0, 1)
randomList = tools.initRepeat(list, zeroOrOne, 30)
或者,我们可以利用toolbox的优势,如下:
toolbox.register("zeroOrOne", random.randint, 0, 1)
randomList = tools.initRepeat(list, toolbox.zeroOrOne, 30)
这里,我们不是显式地定义zeroOrOne()函数,而是创建zerosOrOne算子(或别名),调用具有固定参数0和1的函数random.radint()。
创建fitness
Fitness类定义确定其策略(如,最大化或最小化)的fitness权重,实际的fitness值由各自定义的函数求得。fitness计算函数一般使用toolbox模块登记为别名evaluate,代码如下:
def someFitnessCalculationFunction(individual):
return _some_calculation_of_the_fitness
toolbox.register("evaluate",someFitnessCalculationFunction)
在这个例子中,someFitnessCalculationFunction()对每个个体计算fitness,evaluate登记为其别名。
更多推荐
DEAP 框架(遗传算法)模块笔记
发布评论