18

サイズの配列が与えられた場合、n各インデックスに対してランダムな確率を生成したいと思います。Sigma(a[0]..a[n-1])=1

考えられる結果の1つは次のとおりです。

0     1     2     3     4
0.15  0.2   0.18  0.22  0.25

別の完全に合法的な結果は次のようになります。

0     1     2     3     4
0.01  0.01  0.96  0.01  0.01

これらを簡単かつ迅速に生成するにはどうすればよいですか?どの言語でも答えは問題ありません。Javaをお勧めします。

4

6 に答える 6

22

n個の乱数を取得し、それらの合計を計算し、各数値を合計で割って合計を1に正規化します。

于 2010-01-31T09:01:05.140 に答える
18

あなたが達成しようとしているタスクは、N次元ユニットシンプレックスからランダムな点を描くことと同じです。

http://en.wikipedia.org/wiki/Simplex#Random_samplingが役立つかもしれません。

素朴な解決策は次のようになります。

public static double[] getArray(int n)
    {
        double a[] = new double[n];
        double s = 0.0d;
        Random random = new Random();
        for (int i = 0; i < n; i++)
        {
           a [i] = 1.0d - random.nextDouble();
           a [i] = -1 * Math.log(a[i]);
           s += a[i];
        }
        for (int i = 0; i < n; i++)
        {
           a [i] /= s;
        }
        return a;
    }

N次元単位のシンプレックスから均一に点を描画するには、指数分布の確率変数のベクトルを取得し、それらの変数の合計で正規化する必要があります。指数分布の値を取得するにはlog、一様分布の値の負の値を取ります。

于 2010-01-31T09:14:29.370 に答える
2

これは比較的遅いですが 、サンプリングを均一にする@dreevesによって指摘された、このペーパーで与えられた@Kobiの単純で直接的な答えの修正を示すためです。方法(私がそれをはっきりと理解している場合)は

  1. [1、2、...、M-1]の範囲からn-1個の異なる値を生成します。
  2. 結果のベクトルを並べ替える
  3. 結果のベクトルの最初と最後の要素として0とMを追加します。
  4. x i --x i-1を計算して新しいベクトルを生成します。ここで、i = 1,2、...nです。つまり、新しいベクトルは、古いベクトルの連続する要素間の差で構成されます。
  5. 新しいベクトルの各要素をMで除算します。一様分布になります。

明確なランダム値を生成し、それらの合計で割って1に正規化しても、一様分布が生成されるかどうかを知りたいです。

于 2015-11-14T10:22:02.957 に答える
0

正規分布から効率的に値を生成したい場合は、ボックスミュラー変換を試してください。

于 2010-01-31T19:23:44.443 に答える
0

n個の乱数を取得し、それらの合計を計算し、各数値を合計で割って合計を1に正規化します。

Kobiの答えを拡張して、まさにそれを行うJava関数を次に示します。

public static double[] getRandDistArray(int n)  {
    double randArray[] = new double[n];
    double sum = 0;

    // Generate n random numbers
    for (int i = 0; i < randArray.length; i++) {
        randArray[i] = Math.random();
        sum += randArray[i];
    }

    // Normalize sum to 1
    for (int i = 0; i < randArray.length; i++) {
        randArray[i] /= sum;
    }
    return randArray;
}

テスト実行でgetRandDistArray(5)、次を返しました

[0.1796505603694718, 0.31518724882558813, 0.15226147256596428, 0.30954417535503603, 0.043356542883939767]
于 2017-04-02T17:27:25.420 に答える
0
public static double[] array(int n){

    double[] a = new double[n];
    double flag = 0;

    for(int i=0;i<n;i++){
        a[i] = Math.random();
        flag += a[i];
    }

    for(int i=0;i<n;i++) a[i] /= flag;

    return a;
}

ここで、最初乱数を格納します。そして、フラグは生成されたすべての数値の合計を保持するため、次のforループで生成された数値はフラグで除算され、最後に配列は確率分布で乱数を持ちます。

于 2018-09-09T13:25:19.320 に答える