13

我尝试为我的项目学习和实现一个简单的遗传算法库。在这个时候,进化,人口选择已经准备好了,我正试图在Java和Scala中为我的遗传进化引擎实现一个简单的好突变算子,如Gaussian mutation operator(GMO)。如何在Java中实现遗传算法的高斯变异算子

我发现高斯变异算(GMO)的一些信息进纸A mutation operator based on a Pareto ranking for multi-objective evolutionary algorithms(PM刁,一阿尔贝托),第6页和7

但我有一些问题,以找到如何等信息在Java中实现此运算符的高斯变异运算符和其他有用的变体。我该怎么办?

我使用随机的Java UTIL的random.nextGaussian()功能,但这种方法只返回一个随机数

0和1之间所以,

一)我怎样才能修改返回的精度在这种情况下的数字? (例如,我想获得一个0到1之间的随机双数,步长等于0.00001。)

b)以及如何为此函数指定musigma,因为我想在本地搜索一个值我的基因组,而不是-1和1之间。我怎样才能调整我的基因组价值的地方研究?

编辑1:经过研究,我找到了b)问题的答案。看来我可以取代这样的高斯随机数:

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

其中mean =我的基因组值。

(参看在How can I generate random numbers with a normal or Gaussian distribution?底页的方法)

+0

究竟你“的回归数的精确度”是什么意思? – NPE 2011-06-08 10:13:19

+0

逗号后的数字的数字:http://en.wikipedia.org/wiki/Double_precision_floating-point_format – reyman64 2011-06-08 10:36:07

+0

用什么方式来“修改”“逗号后的数字的数字”? 'nextGaussian'给你一个'double'。你是说这不足以满足你的需求吗? – NPE 2011-06-08 10:38:33

回答

4

要回答问题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 
} 
-2

这里是你如何生成0到n之间的随机数:

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

如果你需要一个整数,将其转换为int但添加一个到n,即(int)random(n + 1)

+0

谁低估了 - 为什么? – Bohemian 2011-06-16 23:44:40

3

我强烈建议不要使用Java的随机数发生器。它使用linear congruential generator,已经已知的局限性:

如果需要更高质量的随机数,并有足够的内存可用(〜2千字节),则梅森捻线算法提供了一个大大更长时间(219937-1)和变化的均匀性。[9] Mersenne扭曲产生更高质量的比几乎任何LCG偏离。[引证需要一种常见梅森捻线机实现方式中,有趣的是,使用一个LCG产生种子的数据。*(维基百科)

因此,建议你考虑一个梅森扭曲者的实现。特别是,我正在使用ECJ的实现,该实现也能够生成高斯数字

如果您需要与Java的随机接口兼容使用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更快,但它没有实现随机接口。

+1

我忘了说... nextGaussian从正态分布返回一个样本因为你想改变平均值和您应该应用您在评论中提到的标准转换。有关其他信息,请参阅http://people.math.sfu.ca/~cschwarz/Stat-301/Handouts/node70.html – Matteo 2011-06-17 08:00:00

+0

Thx寻求帮助, m使用SSJ库中的lecuyer的随机生成器和math.commons(apac他基金会)像WEll。我没有答案关于在我的随机double中产生更小的变化:/实际上,我使用1和1E6之间的随机(int)来划分我的随机(双)... – reyman64 2011-06-17 09:15:50

-1

要改变数量的“精确”,做这样的事情:

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

这一轮的变量rand到小数点后2位。当然,你必须小心小的浮点舍入错误,所以它不一定是确切的。

至于实施转基因生物,该文件描述了如何做到相当准确。我不确定如何解释清楚。我假设你的代码中有一个x和一个sigma,你只需使用所描述的数学运算来转换它。