如何用Java实现遗传算法的高斯变异算子
我尝试为我的项目学习并实现一个简单的遗传算法库。此时,进化、种群选择已经准备就绪,我正在尝试实现一个简单的良好变异算子,例如 高斯变异算子 (GMO),用于我的 Java 和 Scala 遗传进化引擎。
我在论文中找到了一些关于高斯变异算子(GMO)的信息变异算子基于多目标进化算法的 Pareto 排名(PM Mateo,I. Alberto),第 6 页和第 7 页。
但是我在查找有关如何在 Java 中实现这个高斯变异算子以及该算子的其他有用变体。我应该怎么办?
我使用 random Java util 的 random.nextGaussian()
函数,但该方法仅返回 0 到 1 之间的随机数。
因此,
a) 如何修改返回数的精度在这种情况下? (例如,我想获得 0 到 1 之间的随机双数,步长等于 0.00001。)
b) 以及如何为此函数指定 mu
和 sigma
,因为我想在本地搜索我的基因组值,而不是在 -1 和 1 之间。我如何围绕我的基因组值调整本地研究?
经过研究,我找到了b)问题的答案。看来我可以像这样替换高斯随机数:
newGenomeValue = oldGenomeValue + (( gaussiandRndNumber * sigma ) + mean )
其中 mean
= 我的基因组值。
I try to learn and implement a simple genetic algorithm library for my project. At this time, evolution, selection of population is ready, and I'm trying to implement a simple good mutation operator like the Gaussian mutation operator (GMO) for my genetic evolution engine in Java and Scala.
I find some information on Gaussian mutation operator (GMO) into the paper A mutation operator based on a Pareto ranking for multi-objective evolutionary algorithms (P.M. Mateo, I. Alberto), page 6 and 7.
But I have some problem to find other information on how to implement this Gaussian mutation operator and other useful variants of this operator in Java. What should I do?
I'm using the random.nextGaussian()
function of random Java util, but this method only returns a random number between 0 and 1.
So,
a) How can I modify the precision of the return number in this case? (For example, I want to get a random double number between 0 and 1 with step equal to 0.00001.)
b) and how can I specify mu
and sigma
for this function, because I want to search locally about a value of my genome, not between -1 and 1. How can I ajust that local research around my genome value?
After research, I found an answer for the b) question. It seems I can displace the Gaussian random number like this:
newGenomeValue = oldGenomeValue + (( gaussiandRndNumber * sigma ) + mean )
where mean
= my genome value.
(Cf. method of bottom page in How can I generate random numbers with a normal or Gaussian distribution?.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
要回答问题 a,您只需四舍五入到最接近的 0.00001 即可得到这些单位的答案。例如:
现在对于 b 部分,您的想法是正确的,并且您提供的代码应该可以工作。您需要做的就是将变量重新调整到所需的范围。我唯一可以补充的是,它起作用的根本原因是微积分中变量定理的变化: http:// /en.wikipedia.org/wiki/Integration_by_substitution
如果您在平均值为 0、标准差为 1 的高斯分布通过线性平移和重新缩放,然后你会发现你写的确实是正确的。
把它们放在一起,下面是一些可以解决这个问题的代码:
To answer question a, all you have to do is round to the nearest 0.00001 to get your answer in those units. For example:
Now for part b, you have the right idea and the code you presented should work. All you need to do is rescale your variable to the desired range. The only thing I can add is that the underlying reason this works is the change of variables theorem from calculus: http://en.wikipedia.org/wiki/Integration_by_substitution
If you work out this formula in the case of a Gaussian distribution with 0 mean and standard deviation 1 being transformed by a linear shift and a rescaling, then you will see that what you wrote out was indeed correct.
Putting it all together, here is some code that should do the trick:
我强烈建议不要使用 Java 的随机数生成器。它使用线性同余生成器,它具有已知的局限性:
因此,我建议您考虑梅森扭曲器实现。特别是,我正在使用 ECJ 的实现,它还能够生成高斯数。
如果您需要与 Java 的 Random 接口兼容,请使用 http://code.google.com/p/ecj/source/browse/trunk/ecj/ec/util/MersenneTwister.java。
http://code.google.com /p/ecj/source/browse/trunk/ecj/ec/util/MersenneTwisterFast.java 速度更快,但它没有实现 Random 接口。
I strongly suggest to DO NOT use the Java's random number generator. It uses the linear congruential generator, which has known limitations:
Accordingly, I suggest you to consider a Mersenne twister implementation. In particular, I'm using the ECJ's implementation, which also has the ability to generate Gaussian numbers.
If you need compatibility with Java's Random interface use http://code.google.com/p/ecj/source/browse/trunk/ecj/ec/util/MersenneTwister.java.
http://code.google.com/p/ecj/source/browse/trunk/ecj/ec/util/MersenneTwisterFast.java is faster, but it does not implement the Random interface.
以下是生成 0 到 n 之间的随机数的方法:
如果您需要一个整数,请将其转换为
int
但将 1 加到 n,即(int)random(n + 1)< /代码>
Here's how you can generate a random number between 0 and n:
If you need an integer, cast it to
int
but add one to n, ie(int)random(n + 1)
要更改数字的“精度”,请执行以下操作:
这会将变量
rand
四舍五入到小数点后两位。当然,您必须小心小的浮点舍入误差,因此它不一定准确。至于实施转基因生物,论文非常精确地描述了如何实施。我不确定如何可以更清楚地解释它。我假设您的代码中某处有一个
x
和一个sigma
,并且您只需使用所描述的数学运算对其进行转换。To change the "precision" of the number, do something like:
This will round the variable
rand
to 2 decimal places. Of course, you'll have to be careful about small floating point rounding errors so it won't necessarily be exact.As for the implementing the GMO, the paper describes how to do it pretty precisely. I'm not sure how it could be explained any clearer. I'm assuming you have an
x
and asigma
somewhere in your code and you just transform it using the mathematical operation described.