我想为终端变量提供实值指数(不仅仅是整数)。例如,假设我想进化一个函数 y = x^3.5 + x^2.2 + 6。我应该如何进行?我还没有看到任何可以做到这一点的 GP 实现。我尝试使用幂函数,但有时初始解决方案的指数太多,以至于评估值超过了“双”界限!任何建议将不胜感激。提前致谢。
4 回答
如果只有一些初始种群遭受溢出问题,那么只需以较差的适应度得分惩罚它们,它们可能会在几代之内从种群中移除。
但是,如果问题是几乎所有个人都遭受这个问题的困扰,那么您将不得不添加一些约束。最简单的做法是将幂函数的指数子项限制为真正的文字 - 这意味着不允许嵌套幂。这取决于这是否足以满足您的需求。有几种方法可以添加这些(或更复杂的)约束 - 尝试查看约束句法结构和语法引导的 GP。
其他一些简单的想法:您可以使用更大范围的数据类型吗?此外,您可以减少最大深度参数,以便嵌套指数的空间更少。当然,这只是在一定程度上是可能的,这取决于功能的复杂性。
DEAP(在 Python 中)实现了它。事实上,有一个例子。通过将 Python 中的 math.pow 添加到原始集中,您可以实现您想要的。
pset.addPrimitive(math.pow, 2)
但是使用 pow 运算符可能会得到类似 x^(x^(x^(x))) 的东西,这可能是不希望的。你应该添加一个限制(通过一种我不确定的方式)在你的树中允许战俘的位置(就在一片叶子或类似的东西之前)。
OpenBeagle(在 C++ 中)也允许,但您需要使用来自的 pow 开发自己的原语<math.h>
,您可以使用 Sin 或 Cos 原语作为示例。
整数与实数具有不同的二进制表示,因此您必须使用稍微不同的位串表示和重组/变异运算符。
有关出色的演示,请参见 www.cs.vu.nl/~gusz/ecbook/slides/Genetic_Algorithms.ppt 的幻灯片 24 或查看 Eiben/Smith 的书“进化计算遗传算法简介”。这描述了如何将位串映射到实数。然后,您可以创建一个表示,其中 x 仅位于区间 [y,z] 内。在这种情况下,选择 y 和 z 的数量级小于您正在使用的数据类型的容量(例如 10^308 表示双精度),这样您就不会遇到您描述的溢出问题。
您必须考虑使用实数指数和负基数,您将不会获得实数,而是复数。例如,.NET 中的Math.Pow实现表明,如果您尝试计算负基数对非整数指数的幂,则会得到 NaN。您必须确保所有 x 值都是正数。我认为这就是您“超过双重界限”时看到的问题。
顺便说一句,您可以尝试HeuristicLab GP 实现。它具有可配置的语法非常灵活。