5

ANSI rand()関数のみを使用して、任意の確率分布で疑似乱数浮動小数点数を生成する簡単なアルゴリズムを探しています。単純な一様分布の場合、次のコードを使用します。

x = (float)rand() / (float)RAND_MAX;

もちろん、それはあまり正確ではありませんが、私のニーズには十分です。ロジスティックやガウス分布のような他の分布も必要です。理想的には、有限長の単純なベクトルを使用して任意のpdfを定義する必要があります。たとえば、ロジスティックpdfの場合、このベクトルは次のようになります。

logistic_pdf = {0., 0.26894, 0.33924, 0.41742, 0.5, 0.58257, 0.66075, 1.};

均一の場合(同じ次元8を使用):

uniform_pdf = {0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125};

これは単なるアイデアです。しかし、それを効率的に実装する方法がわかりませんrand()->{0...RAND_MAX}

4

5 に答える 5

3

任意の複雑なことを行うための単純なアルゴリズムはありません。'任意の'分布ごとに逆確率積分変換を見つける必要があります。

于 2012-11-30T15:56:41.177 に答える
2

あなたの質問には簡単な答えがありません。Luc Devroye は 800 ページ以上を費やして、彼のテキスト " Non-Uniform Random Variate Generation " で非常に包括的に対処しました。

于 2014-04-01T17:02:31.720 に答える
2

任意の離散分布のための線形時間初期化定数時間サンプリング アルゴリズムがあります。

http://web.eecs.utk.edu/~vose/Publications/random.pdf

見てみな!それは非常に巧妙で、実装するのはまったく難しくありません。

于 2013-04-17T12:18:21.167 に答える
1

このリンクを見てください。ポアソン分布の例を次に示します。

#include < stdlib.h > 
#include < math.h >

int Poisson ( double ev ) {
      int         n = 0;      // counter of iterations 
      double      em;         // e^(-ev), where v is the expected value
      double      x;          // pseudorandom number

      em = exp (-ev);
      x = rand() / (double) RAND_MAX;     // check your C compiler docs
                                          // for the correct constant name
      while (x > em) { 
            n++;
            x *=  rand() / (double) RAND_MAX;
            }
      return n;
      } 

main () {
  int i;
  for (i = 0; i< 1000; i++) {
    printf("new Poisson value: %d\n", Poisson(.133333) );
    }
  }
于 2012-11-30T12:26:30.893 に答える
0

これらの分布のそれぞれから疑似乱数を引き出す方法が異なるため、いくつかの調査を行う必要があります。妥当な出発点はウィキペディアです。正規/ガウス分布ロジスティック分布から値を生成する方法があります。他に興味深いのは、指数分布ベータ分布、およびガンマ分布です。

または、複製したいソース データがある場合は、そのデータのヒストグラムを作成し、そのデータから CDF を生成できます。次に、単純に X~U(0,1) を生成し、これが対応するヒストグラムのビンを決定し、ビンの上限と下限の間で線形にスケーリングします。これが、スタファンが言及している逆確率積分変換法の本質です。

于 2012-11-30T15:29:44.070 に答える