如何用Java实现遗传算法的高斯变异算子

发布于 2024-11-14 13:08:27 字数 1039 浏览 3 评论 0原文

我尝试为我的项目学习并实现一个简单的遗传算法库。此时,进化、种群选择已经准备就绪,我正在尝试实现一个简单的良好变异算子,例如 高斯变异算子 (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) 以及如何为此函数指定 musigma ,因为我想在本地搜索我的基因组值,而不是在 -1 和 1 之间。我如何围绕我的基因组值调整本地研究?

经过研究,我找到了b)问题的答案。看来我可以像这样替换高斯随机数:

 newGenomeValue = oldGenomeValue + (( gaussiandRndNumber * sigma ) + mean )

其中 mean = 我的基因组值。

(参见底部页面的方法如何生成正态分布或高斯分布的随机数?< /a>。)

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

时光匆匆的小流年 2024-11-21 13:08:27

要回答问题 a,您只需四舍五入到最接近的 0.00001 即可得到这些单位的答案。例如:

  step = 0.00001;
  quantized_x = step * Math.rint(x / step);

现在对于 b 部分,您的想法是正确的,并且您提供的代码应该可以工作。您需要做的就是将变量重新调整到所需的范围。我唯一可以补充的是,它起作用的根本原因是微积分中变量定理的变化: http:// /en.wikipedia.org/wiki/Integration_by_substitution

如果您在平均值为 0、标准差为 1 的高斯分布通过线性平移和重新缩放,然后你会发现你写的确实是正确的。

把它们放在一起,下面是一些可以解决这个问题的代码:

double next_gaussian()
{
    double x = rng.nextGaussian();  //Use whichever method you like 
                                    //here to generate an initial [-1,1] gaussian distribution

    y = (x * 0.5) + 0.5;                //Rescale to [0,1]

    return Math.rint(y * 100000.0) * 0.00001; //Quantize to step size 0.00001
}

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:

  step = 0.00001;
  quantized_x = step * Math.rint(x / step);

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:

double next_gaussian()
{
    double x = rng.nextGaussian();  //Use whichever method you like 
                                    //here to generate an initial [-1,1] gaussian distribution

    y = (x * 0.5) + 0.5;                //Rescale to [0,1]

    return Math.rint(y * 100000.0) * 0.00001; //Quantize to step size 0.00001
}
万劫不复 2024-11-21 13:08:27

我强烈建议不要使用 Java 的随机数生成器。它使用线性同余生成器,它具有已知的局限性:

如果需要更高质量的随机数,并且有足够的内存可用(~ 2 KB),那么梅森扭曲算法可以提供更长的周期(219937-1)和变量均匀性。 [9]梅森扭曲器生成的偏差比几乎任何 LCG 都更高。[需要引用]有趣的是,常见的梅森扭曲器实现使用 LCG 生成种子数据。*(来自维基百科)

因此,我建议您考虑梅森扭曲器实现。特别是,我正在使用 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:

If higher quality random numbers are needed, and sufficient memory is available (~ 2 kilobytes), then the Mersenne twister algorithm provides a vastly longer period (219937-1) and variate uniformity.[9] The Mersenne twister generates higher-quality deviates than almost any LCG.[citation needed] A common Mersenne twister implementation, interestingly enough, uses an LCG to generate seed data.* (From Wikipedia)

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.

我不是你的备胎 2024-11-21 13:08:27

以下是生成 0 到 n 之间的随机数的方法:

public static double random(int n)
{
    return Math.random() * n;
}

如果您需要一个整数,请将其转换为 int 但将 1 加到 n,即 (int)random(n + 1)< /代码>

Here's how you can generate a random number between 0 and n:

public static double random(int n)
{
    return Math.random() * n;
}

If you need an integer, cast it to int but add one to n, ie (int)random(n + 1)

北陌 2024-11-21 13:08:27

要更改数字的“精度”,请执行以下操作:

((int)(100*rand))/100.0

这会将变量 rand 四舍五入到小数点后两位。当然,您必须小心小的浮点舍入误差,因此它不一定准确。

至于实施转基因生物,论文非常精确地描述了如何实施。我不确定如何可以更清楚地解释它。我假设您的代码中某处有一个 x 和一个 sigma,并且您只需使用所描述的数学运算对其进行转换。

To change the "precision" of the number, do something like:

((int)(100*rand))/100.0

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 a sigma somewhere in your code and you just transform it using the mathematical operation described.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文