Rust Core Edition · v2.7.3 · 更新于

geatpy-rs高性能进化算法工具箱

内核用纯 Rust (PyO3 + abi3) 全部重写的进化算法与遗传算法工具箱。解决原版在 Python 3.11+ 与 Linux ARM64 上装不上的问题,提供全平台预编译 Wheel,原有代码无需改动,内核行为与官方 2.7.0 逐项比对。

pip install geatpy-rs
Python 版本全覆盖
3.8 – 3.15
内核算子 Rust 重写
74
行 unsafe 代码
0
随机差分用例对照官方内核
≈1500
geatpy-rs 架构图与界面展示

Why Rust

为什么做 Rust 重构版本?

原版 Geatpy 长期基于特定版本的 C/C++ 动态链接库,在现代开发与生产环境中面临三个痛点:

  1. 01

    高版本 Python 无法安装

    原版只发布到 Python 3.10 的预编译轮子。Python 3.11、3.12、3.13、3.14 与 3.15 的 C API 变化较大,pip 只能退回源码构建,而原版内核并不随源码公开,基本无法安装。

  2. 02

    ARM 平台覆盖不全

    原版的 Apple Silicon 轮子只覆盖 Python 3.8 ~ 3.10,且没有 Linux ARM64 (aarch64) 轮子,在 ARM 云服务器、树莓派与 Docker 容器里装不上。

  3. 03

    二进制内核难排错

    原版内核是编译好的 C/C++ 二进制:长度为 1 的染色体、一维输入等边界情况会直接段错误,整个 Python 进程退出;还有多处行为与其自身文档不符。

Comparison

核心特性对比

geatpy-rs 与原官方 C/C++ 版本的技术指标对比:

维度原官方版本 (Geatpy)geatpy-rs
底层核心实现早期 C/C++ 动态库,内核以预编译二进制分发纯 Rust 原生实现(crates/geatpy_core),源码公开
Python 版本仅支持 Python 3.5 ~ 3.10Python 3.8 ~ 3.15 全覆盖
ABI 兼容每个 Python 小版本单独构建PyO3 abi3:一次构建,3.8+ 各版本通用
预编译 WheelWindows x86 / x64、Linux x86_64、macOS(Apple Silicon 仅 Python 3.8 ~ 3.10),无 Linux ARM64macOS Universal2(Apple Silicon + Intel)、Linux x86_64 / ARM64、Windows x64
内存安全边界输入可能触发段错误,导致 Python 进程退出纯安全 Rust(无 unsafe),非法输入抛出 Python 异常
多核并行与性能C OpenMP单线程实现(Parallel 参数为兼容保留,暂不生效);36 个经典用例耗时为原版的 0.21 ~ 1.02 倍
随机数与复现取自 numpy 全局随机状态,np.random.seed 可复现与原版一致:np.random.seed / ea.optimize(seed=…) 可完整复现一次运行
API 兼容度基准沿用原有 Python 接口、数据结构与 42 个算法模板;内核行为与官方 2.7.0 二进制逐项差分验证

Parity

与官方 2.7.0 内核的一致性

Rust 内核以官方 geatpy 2.7.0 的二进制为行为基准,通过黑盒差分测试持续验证,期望值均取自官方二进制的实际输出:

  1. 确定性算子逐值比对

    非支配排序、拥挤距离、编码解码、适应度分配、参考点、性能指标、NSGA-III / RVEA 环境选择等,以官方 2.7.0 二进制的实际输出为基准逐值比对。

  2. 随机算子比对统计分布

    交叉、变异、选择等随机算子重复调用数百到数千次,逐元素比对均值分布,确认与官方实现同分布。

  3. 算法模板与经典用例比较解质量

    39 个算法模板在相同问题上比对最终解质量;另有 Ackley、Rastrigin、att48 TSP、ZDT、DTLZ 等 36 个经典用例,覆盖最大化、混合整数、带约束、排列编码、多种群与多染色体模板,两边各运行 30 次比较最优值或 IGD / HV 的分布。除修正了原版迁移缺陷的多种群模板明显更好外,均无显著差异。

  4. 约 1500 个随机差分用例

    随机形状、参数组合与边界值同时在官方二进制与 Rust 内核上运行,逐项比对数值、dtype、返回结构与报错;全整数变量时同样返回 int32,参数校验与报错信息与官方一致。

官方二进制的 12 处已知缺陷(geatpy-rs 按文档修正)
  • ndsortDED 分层错误
  • mergecv 跨行累加
  • tcheby / pbi 在 idealPoint=None 时返回理想点
  • refselect 候选矩阵行序错位
  • migrate 择劣替换实际淘汰的是最优个体
  • migrate 随机替换总是淘汰最后一个个体,完全网状结构会从自身迁入
  • mutgau / mutuni 的 Middle=True 以 (ub-lb)/2 而非区间中点为中心
  • crtip 在边界为小数时生成越界整数
  • pbi 对恰在理想点上的个体返回 NaN
  • crowdis 在目标值含 inf 时返回 NaN
  • cdist 对非连续数组读错数据
  • 染色体长度为 1 或一维输入时 xovsp / xovsh 等段错误

Installation

安装

支持 PyPI 一键安装、GitHub Releases 预编译 Wheel 与源码本地构建三种方式:

pip install geatpy-rs

包名为 geatpy-rs,安装后 Python 代码无需任何改动,继续使用 import geatpy as ea 即可。

Quick Start

代码示例

无需修改原有算法逻辑,用 NSGA-III 求解经典 DTLZ1 三目标优化问题:

example_nsga3_dtlz1.py
import numpy as np
import geatpy as ea  # 沿用原有接口,代码无需改动

class DTLZ1(ea.Problem):
    def __init__(self, M=3):
        name = 'DTLZ1'
        maxormins = [1] * M
        Dim = M + 4
        varTypes = [0] * Dim
        lb = [0] * Dim
        ub = [1] * Dim
        lbin = [1] * Dim
        ubin = [1] * Dim
        ea.Problem.__init__(self, name, M, maxormins, Dim, varTypes, lb, ub, lbin, ubin)

    def aimFunc(self, pop):
        Vars = pop.Phen
        XM = Vars[:, (self.M - 1):]
        g = np.array([100 * (self.Dim - self.M + 1 + np.sum(((XM - 0.5)**2 - np.cos(20 * np.pi * (XM - 0.5))), 1))]).T
        ones_metrix = np.ones((Vars.shape[0], 1))
        pop.ObjV = 0.5 * np.fliplr(np.cumprod(np.hstack([ones_metrix, Vars[:, :self.M - 1]]), 1)) * \
                   np.hstack([ones_metrix, 1 - Vars[:, range(self.M - 2, -1, -1)]]) * np.tile(1 + g, (1, self.M))

if __name__ == '__main__':
    problem = DTLZ1(M=3)
    algorithm = ea.moea_NSGA3_templet(
        problem,
        ea.Population(Encoding='RI', NIND=100),
        MAXGEN=500,
        logTras=1
    )
    res = ea.optimize(algorithm, verbose=True, drawing=1, outputMsg=True, drawLog=True)

Architecture

74 个内核算子全部用 Rust 重写

Rust 内核位于 crates/geatpy_core/,以下是它导出的全部算子,名称与原版一致:

编码与种群初始化

encoding.rs

创建种群、二进制 / 格雷码与实数互转、越界修复

  • crtfld
  • crtbp
  • crtip
  • crtrp
  • crtri
  • crtpp
  • crtpc
  • crtup
  • crtgp
  • bs2ri
  • bs2real
  • bs2int
  • ri2bs
  • boundfix

选择与适应度

selection.rs

锦标赛、轮盘赌、随机遍历抽样等选择,以及适应度排序与缩放

  • tour
  • etour
  • rws
  • sus
  • urs
  • rcs
  • rps
  • ecs
  • otos
  • dup
  • selecting
  • mselecting
  • ranking
  • scaling
  • powing
  • indexing

交叉与重组

recombination.rs

单点 / 两点 / 均匀 / 洗牌交叉,排列编码的 PMX、OX,实数编码的 SBX 等

  • xovsp
  • xovdp
  • xovud
  • xovsh
  • xovbd
  • xovexp
  • xovsec
  • xovpmx
  • xovox
  • recsbx
  • recdis
  • recint
  • reclin
  • recndx
  • recombin

变异

mutation.rs

多项式、高斯、均匀、差分进化变异,以及排列编码的交换、移位、逆转

  • mutpolyn
  • mutgau
  • mutbga
  • mutuni
  • mutbin
  • mutde
  • mutinv
  • mutmove
  • mutswap
  • mutpp
  • mutate

多目标、约束与迁移

multiobjective.rs

非支配排序、拥挤距离、分解聚合、参考点选择、约束合并与多种群迁移

  • ndsortESS
  • ndsortTNS
  • ndsortDED
  • crowdis
  • cdist
  • mergecv
  • tcheby
  • pbi
  • crtidp
  • awGA
  • rwGA
  • refselect
  • refgselect
  • migrate

性能指标

indicator.rs

世代距离、反世代距离、间距与超体积

  • GD
  • IGD
  • Spacing
  • HV

FAQ

常见问题

Python 3.11+ 安装报错、ARM 平台支持、与原版的一致性和迁移问题:

Q1什么是 geatpy-rs?与原版 Geatpy 有什么区别?

geatpy-rs 是经典进化算法工具箱 Geatpy 的 Rust 内核重构版。原版 Geatpy 的内核是只以二进制分发的 C/C++ 动态库,预编译轮子止于 Python 3.10,也没有 Linux ARM64 版本。geatpy-rs 用 Rust(PyO3 + abi3)重写了全部 74 个内核算子,提供 Python 3.8 ~ 3.15 通用的预编译 Wheel,沿用原版的 Python 接口与算法模板,业务代码无需改动即可替换。

Q2为什么在 Python 3.11 及以上版本中 pip install geatpy 会报错?如何解决?

原版 Geatpy 在 PyPI 上只提供 Python 3.5 ~ 3.10 的预编译包。在 Python 3.11、3.12、3.13、3.14 或 3.15 中执行 pip install geatpy 时,pip 找不到匹配的轮子,只能尝试从源码构建,而原版内核并不随源码公开,因此安装失败。解决方法是改装 geatpy-rs:运行 pip install geatpy-rs,即可使用预编译的 abi3 轮子,无需本地安装任何编译器。

Q3geatpy-rs 支持 Apple Silicon (M1 ~ M4) 和 Linux ARM64 吗?

都支持。macOS 提供 Universal2 轮子,同时包含 Apple Silicon 与 Intel 架构,无需 Rosetta 2;Linux 提供 x86_64 与 ARM64 (aarch64) 两种 manylinux2014 轮子,可直接用于 ARM 云服务器与 Docker 容器;Windows 提供 x64 轮子。

Q4原有基于 Geatpy 编写的优化代码需要修改吗?

不需要。geatpy-rs 沿用原版 Geatpy 的 Python 接口,包括问题定义类 ea.Problem、种群 ea.Population、ea.optimize,以及 moea_NSGA3_templet、moea_NSGA2_templet、soea_SEGA_templet 等算法模板和 ndsortESS、crowdis、mutbga、xovdp 等内核算子。安装 geatpy-rs 后仍然 import geatpy as ea,上层代码无需重构。

Q5geatpy-rs 的计算结果与原版一致吗?

一致性经过系统验证。确定性算子以官方 2.7.0 二进制的实际输出为基准逐值比对,随机算子比对统计分布,39 个算法模板比对最终解质量,另有约 1500 个随机差分用例同时在两边运行,逐项比对数值、dtype、返回结构与报错;36 个经典用例两边各运行 30 次,解的质量无显著差异。官方二进制中有多处与其自身文档不符的缺陷(如 ndsortDED 分层错误、mergecv 跨行累加、多种群迁移淘汰最优个体、边界输入段错误),geatpy-rs 按文档实现,并在测试中单独说明;其中多种群模板因此得到明显更好的解。

Q6geatpy-rs 包含哪些进化算法与算子?

42 个单目标与多目标算法模板:NSGA-III、NSGA-II、RVEA、MOEA/D、awGA 等多目标算法,以及 SEGA、SGA、EGA、差分进化 DE、进化策略 ES 等单目标算法。Rust 内核包含 74 个算子:种群初始化与编码转换,锦标赛、轮盘赌等选择,单点 / 两点 / 均匀 / PMX / SBX 等交叉,多项式、高斯、差分进化等变异,ndsortESS 非支配排序、crowdis 拥挤距离、refselect 参考点选择,以及 GD、IGD、Spacing、HV 性能指标。

Q7geatpy-rs 支持多核并行吗?

当前版本的 Rust 内核是单线程实现。原版算子中的 Parallel 参数为兼容而保留,传入不会报错,但暂不生效。即便如此,在 36 个经典用例上 geatpy-rs 的运行耗时为原版的 0.21 ~ 1.02 倍。种群规模较大时,可以在问题类的目标函数里自行使用多进程或向量化计算来提速。

Q8geatpy-rs 的运行结果可以复现吗?

可以。与原版一样,内核的随机数取自 numpy 的全局随机状态:调用 np.random.seed,或给 ea.optimize 传入 seed 参数,同样的代码会得到完全相同的结果。

Open Source & Citation

开源协议与学术引用

本项目基于 LGPL-3.0 协议开源。在科研与学术成果中使用本项目时,请按原项目规范引用:

BibTeX
@misc{geatpy2020,
  author = {Jazzbin, J.},
  title = {Geatpy: The Genetic and Evolutionary Algorithm Toolbox with High Performance in Python},
  year = {2020},
  publisher = {GitHub},
  journal = {GitHub repository},
  howpublished = {\url{https://github.com/geatpy-dev/geatpy}}
}