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,你只需使用所描述的數學運算來轉換它。