跳转到主要内容

pgapack并行遗传算法库的Python封装

项目描述

作者:

Ralf Schlatterbeck <rsc@runtux.com>

新闻

2023年10月新闻

  • 为整数添加差分进化

  • 添加负 assortative 繁殖选项

2023年4月新闻

  • PyPi上最后一次构建对于串行安装是损坏的,它缺少串行版本所需的mpi_stub.c。并行安装仍然是可能的,所以我没注意到,抱歉!

  • 将MPI_Abort添加到包装器中,它在evaluate方法中发生异常时调用

    pga.MPI_Abort (errcode)

    有关如何在运行与MPI部分使用它来在发生异常时终止MPI运行的信息,请参阅下文。

2022年12月新闻:添加回归测试并更新到新的上游,包括几个错误修复。还包括包装器中的几个错误修复。

2022年10月新闻:添加用户定义的数据类型。在examples/gp中使用用户定义的数据类型来实现遗传编程(我们用树数据结构表示表达式)。这使用pgapack中的新序列化API将Python pickle表示传递到对等MPI进程。还纳入了pgapack的最新更改,这优化了重复检查。这对于遗传编程示例中的大型种群大小很有兴趣。请注意,gene_difference方法已重命名为gene_distance

新闻 08-2022:Epsilon约束优化以及一个保留排列的交叉变体(因此,对于整数基因,基因可以表示排列)。

新闻 03-2022:尝试使其在Windows上可安装。这涉及到代码中的某些变通方法,因为可视编译器不支持某些C99结构。

新闻 01-2022:这个版本使用了NSGA-III进行多次评估(注意额外的“I”)。

新闻 12-2021:这个版本从您的目标函数中包装了多个评估值:现在您可以返回多个值,用于约束(必须在优化目标之前满足)或用于与Nondominated Sorting Genetic Algorithm V.2(NSGA-II)的多目标优化。您可以同时使用多目标优化和约束。

新闻:这个版本包装了差分进化方法(这是一个相当老的方法,但在pgapack中是新生成的)。

简介

PGAPy是PGAPack的包装器,一个并行遗传算法库(参见PGAPack Readme),由D. Levine编写,属于数学与计算机科学部,Argonne国家实验室。该库是用C语言编写的。PGAPy为此库提供了Python的包装,以便使用。原始的PGAPack库虽然已经相当老,但它是目前最完整、最精确(虽然这不是将它们包装到Python时的主要关注点)的遗传算法实现之一,具有许多用于实验的铃声和口哨。它还显示出惊人的少量错误。除了正常的“串行”版本外,它还支持通过消息传递接口MPI进行并行执行。这就是为什么我也想在Python中使用它。

要开始使用,您需要PGAPack库,尽管它现在与PGApy捆绑在一起,但要安装一个并行版本,您目前需要为所选的MPI库预编译的PGAPack。有关详细信息,请参阅安装部分。

目前对PGAPy的文档不多。您真的、绝对需要阅读随PGAPack一起提供的文档。PGAPack用户指南现在与PGAPy一起提供。它与一些示例一起安装,安装位置由Python安装程序决定(通常在Linux上为/usr/local/share)。

原始的PGAPack库仍然可以从PGAPack ftp站点下载,它使用ANSI C编写,但可能无法与最新的MPI版本兼容。它也无法与最新的PGAPy版本一起工作。请注意,此版本不再积极维护。我在GitHub上启动了一个PGAPack分支,其中我已经将库移植到最新的MPI标准,并修复了一些文档中的小不一致之处。我还实现了一些新功能,特别是选择方案的增强,称为受限锦标赛替换 [1][2][4],以及最近,差分进化策略 [5][6]。此外,此版本现在支持多目标优化与NSGA-II [7]以及多目标优化与NSGA-III [8][9],并且支持Epsilon约束方法 [10]

注意:当使用NSGA_III替换进行多(或多)目标优化时,您需要执行以下操作之一:

  • 在所有轴偏移1的超平面上设置参考点。这些参考点可以通过方便的函数pga.das_dennis获得,它使用I. Das和J. E. Dennis最初发布的算法创建一个规则的参考点集 [12]。然后,将这些点作为参数reference_points传递给PGA构造函数。

    有关使用示例和用户指南的参考文献,请参阅examples/dtlz2.py。该函数获取目标空间的维数(num_eval减去num_constraint)和要使用的分区数。

  • 或者使用reference_directions参数设置参考方向(在目标空间中),使用refdir_partitions参数设置这些方向的数量(参见上文的das_dennis,这使用Das/Dennis点内部),并使用参数refdir_scale设置一个比例因子。

您可以同时设置这两个参数,这些参数不是互斥的。

我主要在Linux上测试pgapy。但最近我也让它能在Windows上运行,但我并不是非常积极地测试Windows。如果您在Windows上运行它,无论是成功还是不成功,请让我知道。

如上所述,您可以在GitHub上找到我的PGAPack分支,该存储库包含git中的三个上游版本作为版本,并包含有关支持更新的MPI版本和文档更新的某些更新。我还将补丁包含在软件包的Debian维护者Dirk Eddelbuettel的git存储库中。我正在积极维护该分支,添加新功能和错误修复。

为了帮助您开始,我在“examples”中包含了几个非常简单的示例,例如,one-max.py实现了类似于PGAPack文档中的一个“Maxbit”示例。这些示例灵感来源于《Python遗传算法》一书,但都是从头编写的,不包含书中的任何代码。这些示例说明了几个要点。

  • 您实现遗传算法的类需要从pga.PGA(pga是PGAPy包装模块)继承。

  • 您需要定义一个名为evaluate的评估函数,该函数返回一个表示给定基因适应度的数字序列。它通过使用get_allele方法获取基因的等位基因值,这些参数是ppop。有关更多详细信息,请参阅PGAPack文档。您的函数返回的评估次数由构造函数参数num_eval定义,此参数的默认值为1。如果您的评估函数不返回多个评估(使用默认的num_eval设置),则可以返回一个只有一个元素的序列或单个返回值。

  • 当使用多个评估时,这些评估可以用于约束(默认)或多目标优化。在后一种情况下,约束的数量(默认情况下比使用参数num_eval设置的评估次数少一个)必须设置为至少为两个目标留下两个评估的数字。可以使用参数num_constraint设置约束的数量。在多目标优化中使用时,您需要一个两种替换类型之一PGA_POPREPL_NSGA_IIPGA_POPREPL_NSGA_III,使用pop_replace_type参数设置。

  • 可以定义额外的函数来覆盖PGAPack库的内置函数,例如print_string的示例。请注意,我们可以调用我们的PGA超类的原始print_string方法。以相同的方式,您可以实现,例如,您自己的交叉方法。

  • 类的构造函数需要定义基因类型,在示例中我们使用了int和bool内置数据类型。

  • 基因的长度需要在构造函数中给出。

  • 我们通常希望最大化评估函数返回的数字,如果您想最小化,将参数maximize设置为False。

  • 对于非二进制基因,我们可以定义一个初始化值的数组,每个条目包含一个包含下限和上限的序列。该数组必须与基因的长度相同。请注意,上限包含在可能值的范围内(与python范围运算符不同,但与PGAPack定义兼容)。

  • 在类的构造函数中,我们可以添加遗传算法的参数。并非所有PGAPack参数都已包装,目前您需要查阅PGAPy的源代码以找出哪些参数已包装。在示例中,我们定义了几个打印选项。

  • 最后,使用run方法启动遗传算法。

PGAPy的命名约定

当您扩展PGAPy时——请记住并非所有PGAPack函数都已包装,您可能需要额外的函数——在做出更改时,您应该坚持我的命名约定。以下命名约定用于包装器

  • PGAPack的常量,如PGA_REPORT_STRING,按原样以大写形式使用。这些常量可以直接从包装模块导入。到目前为止,并非所有常量都已包装,如果您需要更多,请将它们添加到pgamodule.c中的constdef数组,并发送补丁给我。

  • 对于pga.PGA类的各种方法,我已经移除了PGAPack中使用的全局< span class="docutils literal">PGA前缀,并将原始函数名中的大写单词之间用下划线连接,转换为小写,例如< span class="docutils literal">PGARun变为< span class="docutils literal">run,< span class="docutils literal">PGACheckStoppingConditions变为< span class="docutils literal">check_stopping_conditions。但是,如果名称中包含“GA”(表示“遗传算法”),则例外,所以< span class="docutils literal">PGASetMaxGAIterValue变为< span class="docutils literal">max_GA_iter。

  • 尽可能地将PGAPack需要为每种数据类型分别提供的函数合并为单个类方法,因此< span class="docutils literal">PGAGetBinaryAllele、< span class="docutils literal">PGAGetCharacterAllele、< span class="docutils literal">PGAGetIntegerAllele、< span class="docutils literal">PGAGetRealAllele都变为< span class="docutils literal">get_allele。同样,对于< span class="docutils literal">set_allele也是如此。

  • 每当PGAPack中的名称带有“Value”或“Flag”后缀时,我都会省略它,因此< span class="docutils literal">PGAGetFitnessCmaxValue变为< span class="docutils literal">fitness_cmax,< span class="docutils literal">PGAGetMutationAndCrossoverFlag变为< span class="docutils literal">mutation_and_crossover。唯一的例外是两个函数< span class="docutils literal">PGAGetMutationRealValue和< span class="docutils literal">PGAGetMutationIntegerValue,它们变为< span class="docutils literal">mutation_value,而不仅仅是< span class="docutils literal">mutation。

  • 某些字段可以接受多个值(它们通过按位或整数常量实现,在Python中,它们指定为常量的列表或元组)。如果这些字段在PGAPack中不是复数(如果不是复数),则将它们转换为复数,例如,< span class="docutils literal">PGASetStoppingRuleType变为< span class="docutils literal">stopping_rule_types。

  • 包装程序中的内部方法名称以PGA_开头,因此类方法< span class="docutils literal">set_allele通过C函数< span class="docutils literal">PGA_set_allele在< span class="docutils literal">pgamodule.c中实现。

构造函数参数

PGAPack有很多用于设置参数的< span class="docutils literal">PGASet和< span class="docutils literal">PGAGet函数。这些函数一方面反映在构造函数参数中,另一方面反映在(通常是只读的,但请参见下文)< span class="docutils literal">PGA对象的属性中。以下表格概述了所有原始PGAPack名称和Python包装器的名称。对于PGAPack名称,我只列出了< span class="docutils literal">PGASet函数,在许多情况下,有一个相应的< span class="docutils literal">PGAGet函数。如果构造函数参数存在相应的只读属性,则在“Prop”列中指示。在某些情况下,由于PGAPack中没有实现相应的< span class="docutils literal">PGAGet函数,因此属性缺失,在其他情况下,返回具有PGApy中符号常量的数值在意义上并不太多。

属性与构造函数参数具有相同的名称。有一些属性没有相应的构造函数参数,即< span class="docutils literal">eval_count属性(返回函数评估的计数),返回当前GA代数的< span class="docutils literal">GA_iter属性,以及返回当前进程MPI排名的< span class="docutils literal">mpi_rank属性(这归入PGAGetRank)。

在类型列中,我列出了Python类型。如果类型后跟一个数字,则表示该类型的多个项目被指定(Python中的序列)。一些条目包含“sym”,这些是具有符号常数的整数值,值“msym”表示可以给出由符号常数的列表表示的几个值。特殊情况是PGASetRealInitRangePGASetRealInitPercentPGASetIntegerInitRange函数。这些为基因的每个等位基因取两个值。在Python中,这是一个2元组的序列。请注意,这意味着可以为每个等位基因有不同的允许值范围。

num_eval属性是特殊的:由于C编程语言的限制,在C中进行多次评估时,第一个评估作为evaluate函数的函数返回值返回,所有其他参数都返回在一个辅助数组中。PGAPack指定要返回的辅助评估次数。在Python中,评估函数可以始终返回一个评估值的序列,而num_evalPGAGetNumAuxEval返回的值多1。默认情况下,num_eval为1。

前两个(必需)构造函数参数是基因的类型(这需要一个Python类型,例如,对于二进制基因组使用bool,对于整数基因组使用int)和长度。请注意,string_length通过length参数隐式设置。也可以使用Python内置的len函数将string_length作为PGA对象的长度的值。

现在也可以在优化器运行期间设置一些属性。这些目前是crossover_probepsilon_exponentmulti_obj_precisionp_tournament_probuniform_crossover_prob。只需将优化器(PGA.pga对象的子代)的成员变量赋值即可。

PGAPack名称

构造函数参数

类型

属性

PGASetCrossoverBoundedFlag

crossover_bounded

int

yes

PGASetCrossoverBounceBackFlag

crossover_bounce_back

int

yes

PGASetCrossoverSBXEta

crossover_SBX_eta

float

yes

PGASetCrossoverSBXOncePerString

crossover_SBX_once_per_string

int

yes

PGASetCrossoverProb

crossover_prob

float

yes

PGASetCrossoverType

crossover_type

sym

no

PGASetDEAuxFactor

DE_aux_factor

double

yes

PGASetDECrossoverProb

DE_crossover_prob

double

yes

PGASetDECrossoverType

DE_crossover_type

sym

no

PGASetDEDither

DE_dither

double

yes

PGASetDEDitherPerIndividual

DE_dither_per_individual

bool

yes

PGASetDEJitter

DE_jitter

double

yes

PGASetDENumDiffs

DE_num_diffs

int

yes

PGASetDEProbabilityEO

DE_probability_EO

double

yes

PGASetDEScaleFactor

DE_scale_factor

double

yes

PGASetDEVariant

DE_variant

sym

yes

PGASetEpsilonExponent

epsilon_exponent

float

yes

PGASetEpsilonGeneration

epsilon_generation

int

yes

PGASetEpsilonTheta

epsilon_theta

int

yes

PGAGetEvalCount

eval_count

int

yes

PGASetFitnessCmaxValue

fitness_cmax

float

yes

PGASetFitnessMinType

fitness_min_type

sym

yes

PGASetFitnessType

fitness_type

sym

yes

PGAIntegerSetFixedEdges

fixed_edges

no

PGAIntegerSetFixedEdges

fixed_edges_symmetric

bool

no

PGAGetGAIterValue

GA_iter

int

yes

PGASetIntegerInitPermute

integer_init_permute

int2

no

PGASetIntegerInitRange

init

no

PGASetMaxFitnessRank

max_fitness_rank

float

yes

PGASetMaxGAIterValue

max_GA_iter

int

yes

PGASetMaxNoChangeValue

max_no_change

int

no

PGASetMaxSimilarityValue

max_similarity

int

yes

PGASetMixingType

mixing_type

sym

no

PGASetMultiObjPrecision

multi_obj_precision

int

yes

PGASetMutationAndCrossoverFlag

mutation_and_crossover

int

yes

PGASetMutationBounceBackFlag

mutation_bounce_back

int

yes

PGASetMutationBoundedFlag

mutation_bounded

int

yes

PGASetMutationIntegerValue

mutation_value

int

yes

PGASetMutationOrCrossoverFlag

mutation_or_crossover

int

yes

PGASetMutationPolyEta

mutation_poly_eta

float

yes

PGASetMutationPolyValue

mutation_poly_value

float

yes

PGASetMutationProb

mutation_prob

float

yes

PGASetMutationRealValue

mutation_value

float

yes

PGASetMutationType

mutation_type

sym

no

PGASetNAMWindowSize

nam_window_size

int

yes

PGASetNoDuplicatesFlag

no_duplicates

int

no

PGASetNumAuxEval

num_eval

int

yes

PGASetNumConstraint

num_constraint

int

yes

PGASetNumReplaceValue

num_replace

int

yes

PGASetPopSize

pop_size

int

yes

PGASetPopReplaceType

pop_replace_type

sym

no

PGASetPrintFrequencyValue

print_frequency

int

yes

PGASetPrintOptions

print_options

msym

no

PGASetPTournamentProb

p_tournament_prob

float

yes

PGASetRandomizeSelect

randomize_select

int

yes

PGASetRandomSeed

random_seed

int

yes

PGAGetRank

mpi_rank

int

yes

PGASetRealInitRange

init

no

PGASetRealInitPercent

init_percent

no

PGASetReferenceDirections

refdir_partitions

int

no

PGASetReferenceDirections

refdir_scale

double

no

PGASetReferenceDirections

reference_directions

no

PGASetReferencePoints

reference_points

no

PGASetRestartFlag

restart

int

yes

PGASetRestartFrequencyValue

restart_frequency

int

yes

PGASetRTRWindowSize

rtr_window_size

int

yes

PGASetSelectType

select_type

sym

no

PGASetStoppingRuleType

stopping_rule_types

msym

no

PGASetStringLength

string_length

int

yes

PGASetSumConstraintsFlag

sum_constraints

int

yes

PGASetTournamentSize

tournament_size

int

yes

PGASetTournamentWithReplacement

tournament_with_replacement

int

yes

PGASetTruncationProportion

truncation_proportion

float

yes

PGASetUniformCrossoverProb

uniform_crossover_prob

float

yes

注意:mutation_or_crossover 和 mutation_and_crossover 参数已弃用,请使用 mixing_type 代替!

PGA对象方法

以下是在遗传搜索运行期间可以使用的方法。使用 run 方法来启动搜索。这可以用于,例如,在自定义 endofgen 方法中的爬山过程中设置等位基因。请注意,某些方法仅适用于某些基因类型,例如 encode_int_ 方法只能用于二进制等位基因(它们将整数值编码为二进制或灰度代码表示形式到基因中)。其他方法根据基因类型接收或返回不同的类型,例如 get_alleleset_allele,它们根据基因类型调用不同的后端函数。使用 set_random_seed 方法,可以重新播种随机数生成器。通常最好在(在)开始时(之前)通过在构造函数中指定 random_seed 来播种生成器。有关更多详细信息,请参阅用户指南。方法 get_evaluation 将返回单个评估的双精度值和一个双精度元组(当 num_eval > 1 时)

方法

参数

返回值

check_stopping_conditions

如果应停止则为 true

encode_int_as_binary

p, pop, frm, to, val

None

encode_int_as_gray_code

p, pop, frm, to, val

None

encode_real_as_binary

p, pop, frm, to l, u, val

None

encode_real_as_gray_code

p, pop, frm, to l, u, val

None

euclidian_distance

p1, pop1 p2, pop2

float

fitness

pop

None

get_allele

p, pop, index

等位基因值

get_best_index

pop

最佳字符串的索引

get_best_report_index

pop, idx

具有 idx 的最佳评估的索引

get_evaluation

p, pop

p 的评估

get_evaluation_up_to_date

p, pop

如果是最新版本则为 true

get_fitness

p, pop

p 的适应度(浮点数)

get_gene

p, pop

获取基因(用户数据类型)

get_int_from_binary

p, pop, frm, to

int

get_int_from_gray_code

p, pop, frm, to

int

get_iteration

已弃用,使用 GA_iter

get_real_from_binary

p, pop, frm, to, l, u

float

get_real_from_gray_code

p, pop, frm, to, l, u

float

random01

0到1之间的浮点数

random_flip

概率

0或1

random_gaussian

均值,标准差

float

random_interval

l, r

介于l和r之间的整数

random_uniform

l, r

介于l和r之间的浮点数

run

None

select_next_index

pop

选中的个体索引

set_allele

p, pop, i, value

None

set_evaluation

p, pop, value

None

set_evaluation_up_to_date

p, pop, status

None

set_gene

p, pop, gen

设置基因(用户数据类型)

set_random_seed

种子

None(使用构造函数!)

用户方法

PGAPack 具有用户函数的概念。这允许自定义遗传算法的不同区域。在 Python 中,它们实现为可以在派生类中更改的方法。必须在派生类中实现的方法之一是 evaluate 函数(尽管技术上它不是 PGAPack 中的用户函数)。它解释基因并返回评估值或评估值的序列,如果您设置了 num_eval 构造函数参数。 PGAPack 从原始评估值计算适应性。对于某些方法,可以向上调用 PGA 类,对于某些方法则不可行(并且在大多数情况下不合理)。请注意,对于 stop_cond 方法,可以使用以下方式调用标准停止条件检查

self.check_stopping_conditions()

以下表格列出了可覆盖的方法及其参数(对于函数签名,省略了第一个参数 self)。请注意,在 PGAPack 中,还有其他用户函数,这些函数对于用户定义的数据类型是必需的,但目前尚未在 Python 中公开。在函数签名中,p 表示个体的索引,pop 表示种群。如果指定了多个个体(例如,对于交叉),则可以跟一个数字。对于交叉,c1c2 表示目标个体(子代)。突变方法的 probability 是介于 0 和 1 之间的浮点值。请记住计算发生突变的数量,并为此返回该值!

方法

调用签名

返回值

向上调用

check_duplicate

p1, pop1, p2, pop2

如果重复则返回 True

no

stop_cond

返回 True 以停止

no

crossover

p1, p2, p_pop, c1, c2, c_pop

None

no

endofgen

None

no

evaluate

p, pop

浮点数序列

no

gene_distance

p1, pop1, p2, pop2

float

no

哈希值

p, pop

int

no

initstring

p, pop

None

no

mutation

p, pop, propability

mutations

no

pre_eval

pop

None

no

print_string

file, p, pop

None

yes

常量

以下 PGAPack 常量可用

常量

描述

PGA_CROSSOVER_EDGE

排列的边缘交叉

PGA_CROSSOVER_ONEPT

一点交叉

PGA_CROSSOVER_SBX

模拟二进制交叉

PGA_CROSSOVER_TWOPT

两点交叉

PGA_CROSSOVER_UNIFORM

均匀交叉

PGA_FITNESSMIN_CMAX

通过减去最坏值映射适应性

PGA_FITNESSMIN_RECIPROCAL

通过倒数映射适应性

PGA_FITNESS_NORMAL

适应性线性归一化

PGA_FITNESS_RANKING

适应性线性排名

PGA_FITNESS_RAW

恒等适应性函数

PGA_MUTATION_CONSTANT

通过添加/减去常数进行突变

PGA_MUTATION_GAUSSIAN

通过选择高斯分布进行突变

PGA_MUTATION_PERMUTE

突变交换两个随机基因

PGA_MUTATION_POLY

多项式突变

PGA_MUTATION_RANGE

用初始范围内的统一选择替换基因

PGA_MUTATION_UNIFORM

从区间均匀变异

PGA_NEWPOP

新种群符号常量

PGA_OLDPOP

旧种群符号常量

PGA_POPREPL_BEST

种群替换最佳字符串

PGA_POPREPL_NSGA_II

使用NSGA-II替换进行多目标优化

PGA_POPREPL_NSGA_III

使用NSGA-III替换进行多目标优化

PGA_POPREPL_PAIRWISE_BEST

比较新旧种群中相同索引

PGA_POPREPL_RANDOM_NOREP

种群替换随机不重复

PGA_POPREPL_RANDOM_REP

种群替换随机重复

PGA_POPREPL_RTR

限制性锦标赛替换

PGA_REPORT_AVERAGE

报告平均评估

PGA_REPORT_HAMMING

报告汉明距离

PGA_REPORT_OFFLINE

离线报告

PGA_REPORT_ONLINE

在线报告

PGA_REPORT_STRING

报告字符串

PGA_REPORT_WORST

报告最差评估

PGA_SELECT_LINEAR

按种群顺序返回个体

PGA_SELECT_PROPORTIONAL

适应度比例选择

PGA_SELECT_PTOURNAMENT

二进制概率锦标赛选择

PGA_SELECT_SUS

随机通用选择

PGA_SELECT_TOURNAMENT

锦标赛选择

PGA_SELECT_TRUNCATION

截断选择

PGA_STOP_MAXITER

在最大迭代次数时停止

PGA_STOP_NOCHANGE

在最大代数没有变化时停止

PGA_STOP_TOOSIMILAR

当个体过于相似时停止

用户定义数据类型

PGAPy的最新版本支持用户定义数据类型。只需定义您的数据类型,并将其作为第二个参数传递给PGA构造函数。框架将在通过MPI(如果您运行的是并行版本)传输数据时处理数据的序列化。

如果通过no_duplicates构造函数参数启用重复检查,则您的数据类型需要定义一个__hash__方法(除非Python默认的哈希方法满足您的需求)。

用户定义的数据类型不使用等位基因,因此正常的get_allele(和set_allele)方法不可用。相反,可以使用get_gene方法检索整个个体,并使用set_gene方法设置。

使用用户数据类型,您需要定义以下方法

  • check_duplicate (self, p1, pop1, p2, pop2)如果您启用交叉参数no_duplicates的重复检查。当两个个体是重复项时应返回True。使用get_gene检索在种群pop1pop2中的个体p1p2的基因。

  • crossover (self, p1, p2, ppop, c1, c2, cpop)对于交叉操作,使用get_gene获取在生成ppop中的父代p1p2的基因,并使用set_gene设置在生成cpop中的子代基因c1c2

  • initstring (self, p, pop)用于初始化给定的字符串,在该方法中使用set_gene将您的对象设置为基因。

  • 使用mutation(self, p, pop, pm)进行变异操作。这个方法应该返回执行变异的数量。如果启用重复检查,框架将反复调用变异算子,将重复的个体变异为非重复的另一个个体。这使用您变异方法的返回值。如果您的变异算子在重复检查启用时偶尔不返回非零的变异次数,您将进入一个无限循环。pm参数给出变异概率。使用get_gene来检索要变异的个体,使用set_gene在变异后更新此个体。

  • 要打印基因对象,使用print_string(self, file, p, pop),使用get_gene来检索要打印的个体。

对于这些方法,通常一个好的做法是永远不要就地修改一个个体:这个个体可能会被反复用于遗传操作(例如变异和交叉),所以在修改它时,您将在后续的遗传操作中产生错误的结果。要复制数据结构,通常使用python模块中的deepcopy函数。

除了上述方法之外,您可能希望使用stop_cond方法定义一个停止规则,或者使用hash方法覆盖哈希计算的方式。计算哈希的默认方法是调用hash(gene),其中gene是用户定义的数据类型的一个对象。其他可能使用的方法是endofgen方法、gene_distance方法(例如,在使用带有PGA_POPREPL_RTR的受限锦标赛选择时),或者pre_eval方法。

有关用户定义数据类型的示例在examples/gp中:这实现了使用树数据结构的遗传编程。请注意,gp.py中的Node类有一个__hash__方法,它通过树的序列化构建哈希(对于具有相同树结构的个体来说是相同的)。

缺少的功能

如前所述,PGAPack中并非所有函数和常量都已被封装——对于许多应用,给定的集应该足够。如果您需要额外的函数,您可能希望封装这些函数并发给我一个补丁。

报告错误

请使用Sourceforge错误跟踪器Github错误跟踪器,并

  • 提供关于您认为的正确行为的简短描述

  • 提供观察到的行为的描述

  • 告诉我您确切做了什么。

  • 如果您可以发布您的源代码,这将使我为您调试错误变得容易得多

资源

Sourceforge主页获取项目信息和下载

或从Github检出

或直接通过pypi安装

安装

PGApy,正如其名所示,支持并行化遗传算法的评估函数。这使用消息传递接口(MPI)标准。

要安装一个串行版本(不使用MPI进行并行编程),您只需使用pip从pypi安装即可。或者,当您已解压或检出源代码时,您可以使用以下方式安装:

python3 setup.py install --prefix=/usr/local

如果您想使用MPI(消息传递接口)库的并行版本,您首先需要安装PGAPack的并行版本。最简单的方法是使用来自github的pgapack deb包构建器。克隆此存储库,检出分支master,安装构建依赖项,它们在文件debian/control中列出,并使用以下命令构建deb包:

dpkg-buildpackage -rfakeroot

这将为debian中所有受支持的MPI库构建pgapack deb包,目前这些是mpichopenmpilam。除了MPI库外,还构建了pgapack库的串行版本。接下来,安装pgapack包和所选的MPI后端库。如果您没有对MPI库的偏好,libpgapack-openmpi是使用Debian默认MPI库偏好的包。

安装PGAPack的并行版本后,您可以通过以下方式安装PGApy:设置PGA_PARALLEL_VARIANT环境变量(mpichopenmpilam之一)并将PGA_MODULE设置为module_from_parallel_install。最后,调用设置,例如:

export PGA_PARALLEL_VARIANT=openmpi
export PGA_MODULE=module_from_parallel_install
python3 setup.py install --prefix=/usr/local

请注意,这同样适用于pip install,即在安装PGAPack的并行版本后,您可以直接使用pip安装。

export PGA_PARALLEL_VARIANT=openmpi
export PGA_MODULE=module_from_parallel_install
pip install pgapy

或者根据您的系统上pip的安装方式选择其他方法。

python3 -m pip install pgapy

如果您的MPI库安装在另一个位置,您应该研究setup.py中的Extension配置,以便得出适合您的安装的扩展定义。如果您的安装对更多人来说很有趣,您可以随意提交一个补丁,将您的扩展配置添加到标准的setup.py

关于较新版本的Python

较新版本的Python已弃用安装到系统Python版本中,即使在/usr/local。您仍然可以本地构建pgapy包并使用安装程序安装。在Debian Linux上,您需要安装以下包:

apt-get install python3-pip python3-dev python3-toml \
    python3-build python3-installer python3-venv python3-sphinx
    netpbm

然后您可以在本地构建并安装。

python3 -m build
python3 -m installer dist/*.whl

更好的方法是,从github克隆我的releasetool包到pgapy的parallel目录中,并使用以下命令构建:

git clone https://github.com/schlatterbeck/releasetool.git

这也会生成一个包含正确版本号的Version.py文件。如果您想安装并行版本,您应该在构建之前设置环境变量

make dist

export PGA_PARALLEL_VARIANT=openmpi
export PGA_MODULE=module_from_parallel_install

使用MPI运行

要使用MPI运行并行版本,必须安装并行版本,请参阅上面安装部分。

对于串行版本,PGAPy确保在evaluate函数中发生异常时终止优化。目前框架不支持将信息返回给rank-0 MPI主进程,因此对于MPI不是这种情况。一个解决方案如下:将您的evaluate方法重命名为_evaluate,并在包装_evaluate的新evaluate方法中捕获异常。如果发生异常,调用MPI_Abort

import traceback
import sys

...

def evaluate (self, p, pop):
    try:
        return self._evaluate (p, pop)
    except Exception:
        # Optionally log exception here
        print (traceback.format_exc ())
        pga.MPI_Abort (1)
        sys.exit (1)

测试

对于测试,最好在安装之前本地构建

python3 setup.py build_ext --inplace

之后,您在本地目录中将有pga.*.so文件。现在您可以使用以下命令运行测试:

python3 -m pytest test

该命令运行所有测试,可能需要一段时间。请注意,测试在examples目录中大多数示例使用不同的命令行参数运行(如果可用)。为了在单个(Python-)进程中执行多次优化运行,我们必须显式调用MPI_Init(而不是依赖PGAPack隐式调用它)。这是因为MPI_Init可能在每个进程中只被调用一次。在test/conftest.py中的固定函数中处理了MPI_InitMPI_Finalize的调用。

覆盖率

对于Python示例,覆盖率可以使用以下方法计算:

python3 -m pytest --cov examples test

或更详细,包括未测试的行:

python3 -m pytest --cov-report term-missing --cov examples test

目前,对pgamodule.c中的C代码进行覆盖率分析仅在Linux上可行——至少,由于我正在Linux上开发,这是我找到包括C代码在内的覆盖率分析方法的结构。为了进行覆盖率分析编译:

export CFLAGS=-coverage
python3 setup.py build_ext --inplace

这将创建一个以.gcno结尾的文件,位于build目录下,通常在x86_64架构上使用python3.9时,类似于build/temp.linux-x86_64-3.9。运行测试将创建以.gcda结尾的统计数据文件。这些是GNU分析器gcov的数据文件。从这些文件中,可以生成可以浏览器查看的.html文件。

lcov --capture --directory . --output-file coverage.info
genhtml coverage.info --output-directory coverage_out

请注意,lcov程序是Linux发行版的一部分。

在MPI下运行

测试可以直接在MPI下运行。请注意,目前pytest--with-mpi选项不支持。此选项假设使用mpi4py包。但是,pgapy只使用来自pgapack的调用,而pgapack会调用MPI。

在MPI下运行使用:

mpirun $MPI_OPTIONS python3 -m pytest test

MPI_OPTIONS可以是,例如:

MPI_OPTIONS=--machinefile ~/.mpi-openmpi --np 8

这将使用位于您主目录中的openmpi机器定义文件和八个进程。

在MPI下运行特别有用,可用于确定C代码覆盖率。假设已安装并行版本的openmpi,代码可以编译为:

PGA_PARALLEL_VARIANT=openmpi
PGA_MODULE=module_from_parallel_install
export CFLAGS=-coverage
python3 setup.py build_ext --inplace

请注意,覆盖率分析使用在构建目录中的文件,这些文件需要在启动并行版本之前存在。否则,每个并行实例都会尝试创建覆盖率文件,导致竞争条件。一旦覆盖率文件就绪,覆盖率框架将确保适当的锁定,以便没有两个进程同时写入同一个覆盖率文件。

通过首先在没有MPI的情况下运行测试,然后以MPI下多个进程的数量运行相同的版本来创建覆盖率文件最佳。在MPI下运行表明,pgamodule.c中的序列化和反序列化代码被调用。

截至目前,我们得到:

Lines:      1423    1475    96.5 %
Functions:   131     133    98.5 %

参考文献

变更

版本 2.4:新上游

  • 包裹负关联交配

  • 允许差分进化用于整数基因

  • 上游修复了与差分进化、RTR种群替换和重复避免的功能交互错误

  • 添加选项在皇家道路示例中使用负关联交配

版本 2.2.2:添加pyproject.toml

  • 添加pyproject.toml –遗憾的是,目前似乎无法在pyproject.toml中描述二进制模块,特别是通过环境变量实现的变体选择,这在setup.py中目前实现

版本 2.2.1:MPI_Abort

  • 将MPI_Abort添加到包装器中

  • 在发布中包含mpi_stub.c(如果设置了某些环境变量,请参见上述安装部分)

版本 2.2:模块目录

  • 将pga C模块放入pga模块中

  • 向pga添加几个仅限Python的模块

  • pga.__init__导出所有内容,以确保兼容性

  • pga.random包含基于pgapack随机数生成器的Python Random类

版本 2.1:回归测试

  • 在测试期间发现的PGAPack错误修复

  • Python包装器的错误修复

  • 大量测试,覆盖包装器C代码 > 90%

版本 2.0:用户定义数据类型

  • 实现用户定义数据类型,请注意,您的数据类型可以是可变大小的,例如,树数据结构。框架负责序列化数据类型,并在使用并行版本时将其传输到远程MPI进程。

  • 当使用构造函数参数no_duplicates启用重复检查时,底层pgapack代码现在使用散列表。这意味着努力不再是与种群大小成二次关系,而是线性关系。

  • examples/gp目录中的遗传编程(GP)示例

  • 将gene_difference方法重命名为gene_distance

版本 1.8:ε约束优化

  • ε约束优化

  • 多目标优化中打印评估的精度,使用此功能使回归测试在AMD上工作,其中第16位或更小的浮点数差异会导致测试失败

  • 排列交叉

  • 版本号:尽量与pgapack匹配,尽管我们可能在最后一位数上有所不同

版本 1.2:具有NSGA-III的多目标优化

  • 实现NSGA-III

版本 1.1.6:多项式变异和模拟二进制交叉(SBX)

  • 模拟二进制交叉(SBX)

  • 多项式变异

版本 1.1.1-1.1.5:PGAPack 小更新,非 Debian 修复

  • 修复非 Debian 系统的 setup.py

  • 更新到最新的 PGAPack,进行了一些小改动

版本 1.1:增加 NSGA-II 多目标优化

  • 包含最新的 pgapack 版本 1.4

  • 此版本增加了 Deb 等人提出的非支配排序遗传算法版本 2 (NSGA-II) 的多目标优化。这利用了之前引入的选项,可以在目标函数中返回多个值。要使用此功能,您需要将 num_constraint 参数设置为某个值,使得您的评估函数返回的一些函数值作为目标函数值(而不是约束)。请参见 examples/multi.py 中的示例。

版本 1.0:增加约束处理

  • 包含最新的 pgapack 版本 1.3

  • 这增加了辅助评估。现在,如果您在构造函数中将 num_eval 参数设置为大于 1,则评估函数可以返回多个浮点值作为序列。目前,额外的评估值用于约束处理。约束值被最小化。一旦它们达到零或负值,它们就不再计算:所有正约束的总和是整体约束违规。有关详细信息,请参阅 Deb 2000 年的论文,请参阅用户指南进行引用。如果您不使用约束,则您的代码无需更改。

  • 此版本可能会改变优化路径。因此,对于随机数生成器的相同种子,您将得到不同的结果,至少如果在搜索过程中有评估相同(但遗传材料不同)的个体。这是由于 pgapack 中排序函数的改变(它从 C 标准库切换到稳定的排序)。

版本 0.9:允许安装并行版本

  • 将 argv(或 sys.argv)传递给 PGACreate

  • 向 setup.py 添加一个段以允许使用针对 MPI 库编译的 pgapack 变体进行并行安装。目前这需要一个预先安装的 pgapack Debian 软件包。

版本 0.8:修复真实突变中的错误

  • 修复最新 pgapack 中的核心转储问题

版本 0.7:封装有重大变化

  • 现在实现了差分进化,请参阅 minfloat 示例和 pgapack 用户指南。

版本 0.6:封装有重大变化

  • 现在封装使用了 Python 标准建议来创建自定义类。

  • 更新文档

  • 重命名 fitness_cmax(从 fitness_cmax_value

  • 更好的参数错误检查

版本 0.5:错误修复发布

  • 现在 setup.py 可以正常工作,之前的版本有一个编码问题

  • 封装一些新方法

  • 修复 PGAPack 截断选择中的错误

版本 0.4:捆绑 PGAPack

  • 现在 PGAPack 软件包被包含为一个 git 子模块。默认情况下,我们针对这个库进行构建

  • 许可证修复:该模块长期以来一直包含一个 COPYING 文件,该文件包含 2 条 BSD 许可证。但 setup.py 和 pgamodule.c 的头文件仍包含另一个许可证。这已经被纠正。

版本 0.3:功能增强,错误修复

移植到 Python3,Python2 仍然受支持,许可证更改。

  • 包装器的 C 代码更新以支持 Python2 和 Python3

  • 更新文档

  • 修复在回调方法发生错误时可能导致的内存泄漏

  • 许可证更改:我们现在有 2 条 BSD 许可证(类似于 PGAPack 的 MPICH 许可证),这之前是 LGPL。

版本 0.2:功能增强,错误修复

64 位支持,更多 PGAPack 函数和属性封装,Readme 更新:Sourceforge 标志,更改章节。

  • 64 位架构的错误修复

  • 更多 PGAPack 的函数和属性封装

  • setup.py 添加构建规则,以便进行 PGAPack 的标准安装构建 - 目前需要编辑 setup.py - 这里应使用自动检测,但这将需要我为测试设置一个带有标准安装的 PGAPack 的机器。

  • 按需添加 Sourceforge 标志

  • 为自动化发布添加“变更”章节

  • __module__ 字符串添加到模块 pga 中的类 PGA。现在在 Python 中调用:: help (pga) 将按预期工作,之前没有为包含的模块提供帮助文本

版本 0.1:初始 freshmeat 通告

PGAPy 是一个用于 PGAPack 的包装器,PGAPack 是一个并行遗传算法库,一个功能强大的遗传算法库。PGAPy 使用 Python 封装了此库。Pgapack 是最具完整性和精确性的遗传算法实现之一,具有许多用于实验的功能。

  • 初始发布

项目详情


下载文件

下载适合您平台的应用程序文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。

源代码分发

PGAPy-2.4.tar.gz (815.5 kB 查看哈希值)

上传时间 源代码

由以下机构支持