13

私は自分のプロジェクトのために単純な遺伝的アルゴリズム ライブラリを学習して実装しようとしています。現時点では、集団の進化、選択の準備ができており、Java と Scala で私の遺伝的進化エンジンにガウス突然変異演算子(GMO) のような単純で優れた突然変異演算子を実装しようとしています。

Gaussian Mutation Operator (GMO) に関する情報を論文A Mutation operator based on a Pareto ranking for multi-objective evolutionary algorithm (PM Mateo, I. Alberto) の 6 ページと 7 ページに見つけました。

しかし、Java でこのガウス突然変異演算子とこの演算子の他の有用なバリアントを実装する方法に関する他の情報を見つけるのに問題があります。私は何をすべきか?

random Java utilの関数を使用していrandom.nextGaussian()ますが、このメソッドは 0 から 1 の間の乱数しか返しません。

そう、

a) この場合、戻り値の精度を変更するにはどうすればよいですか? (たとえば、ステップが 0.00001 に等しい 0 と 1 の間のランダムな倍精度数を取得したい。)

b) また、-1 と 1 の間ではなく、自分のゲノムの値についてローカルで検索したいので、この関数に対してどのようにmuandを指定できますか? どうすればそのローカルな研究を自分のゲノム値に合わせて調整できますか?sigma

調査の結果、b) の質問に対する答えが見つかりました。次のようにガウス乱数を置き換えることができるようです。

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

ここでmean= 私のゲノム値。

( 「How can I generate random numbers with a normal or Gaussian distribution?」の一番下のページの方法を参照してください。)

4

4 に答える 4

5

質問 a に答えるには、最も近い 0.00001 に丸めるだけで、それらの単位で答えを得ることができます。例えば:

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

パート b では、正しいアイデアが得られ、提示したコードが機能するはずです。必要なのは、変数を目的の範囲に再スケーリングすることだけです。私が追加できる唯一のことは、これが機能する根本的な理由は、微積分からの変数定理の変更であるということです: http://en.wikipedia.org/wiki/Integration_by_substitution: 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
}
于 2011-06-25T18:03:34.183 に答える
3

Javaの乱数ジェネレーターを使用しないことを強くお勧めします。線形合同法を使用しますが、これには既知の制限があります。

より高品質の乱数が必要で、十分なメモリが利用できる場合(〜2キロバイト)、メルセンヌツイスターアルゴリズムは非常に長い期間(219937-1)と変量の均一性を提供します。[9] メルセンヌツイスターは、ほとんどの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は高速ですが、ランダムインターフェイスを実装していません。

于 2011-06-17T07:53:12.063 に答える
-1

0からnまでの乱数を生成する方法は次のとおりです。

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

整数が必要な場合は、にキャストしますが、intnに1を追加します。(int)random(n + 1)

于 2011-06-13T09:44:13.893 に答える
-1

数値の「精度」を変更するには、次のようにします。

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

randこれにより、変数は小数点以下2桁に丸められます。もちろん、小さな浮動小数点の丸め誤差に注意する必要があるため、必ずしも正確であるとは限りません。

GMOの実装に関しては、このペーパーでは、それをかなり正確に行う方法について説明しています。どうすればもっと明確に説明できるのかわかりません。xコード内にとがあり、sigma説明されている数学演算を使用して変換することを前提としています。

于 2011-06-23T17:37:12.347 に答える