1

[1,4] の範囲のランダムな整数の配列を生成する Java コードを作成したいと考えています。配列の長さは N で、実行時に提供されます。問題は、範囲 [1,4] が均一に分布していないことです。

ここに画像の説明を入力

これは、N=100 の配列を作成すると、配列内で数値「1」が平均 40 回、数値「2」が 10 回、というように表示されることを意味します。

今のところ、このコードを使用して範囲 [1,4] の一様分布乱数を生成しています。

public static void main(String[] args)
    {
        int N;
        System.out.println();
        System.out.print("Enter an integer number: ");
        N = input.nextInt();
        int[] a = new int[N];
        Random generator = new Random();
        for(int i = 0; i < a.length; i++)
        {
            a[i] = generator.nextInt(4)+1;
        }
    }

上のグラフに示すように、不均一な分布で実装するにはどうすればよいですか?

4

6 に答える 6

9

コードから始めて、これを行う方法は次のとおりです。

public static void main(String[] args){
    int N;
    System.out.println();
    System.out.print("Enter an integer number: ");
    N = input.nextInt();
    int[] a = new int[N];
    Random generator = new Random();
    for (int i = 0; i < a.length; i++) {
        float n = generator.nextFloat();
        if (n <= 0.4) {
            a[i] = 1;
        } else if (n <= 0.7) {
            a[i] = 3;
        } else if (n <= 0.9) {
            a[i] = 4;
        } else {
            a[i] = 2;
        }
    }
}

更新: @pjs の提案で、降格確率の順に数字を選択して、if ブロックを早く終了する傾向があるようにします

于 2014-01-15T15:59:06.130 に答える
3

NavigableMapより一般的なアプローチでは、分布確率を に入力できます。

double[] probs = {0.4, 0.1, 0.2, 0.3};
NavigableMap<Double, Integer> distribution = new TreeMap<Double, Integer>();
for(double p : probs) {
    distribution.put(distribution.isEmpty() ? p : distribution.lastKey() + p, distribution.size() + 1);
}

その後、範囲 [0, 1>:

Random rnd = new Random();
for(int i=0; i<20; i++) {
    System.out.println(distribution.ceilingEntry(rnd.nextDouble()).getValue());
}

これにより、次のキーと値のペアがマップに入力されます。

0.4 -> 1
0.5 -> 2
0.7 -> 3
1.0 -> 4

マップをクエリするには、最初に 0 から 1 の範囲で均一に分散された double を生成します。ceilingEntryメソッドを使用してマップをクエリし、乱数を渡すと、「指定されたキー以上の最小のキーに関連付けられたマッピング」が返されます。たとえば、範囲 <0.4, 0.5] の値を渡すと、マッピングを持つエントリが返され0.5 -> 2ます。getValue()したがって、返されたマップ エントリで使用すると 2 が返されます。

于 2014-01-15T16:21:09.287 に答える
2

Leta1, a2, a3a4be double は相対確率を指定し、s = a1+a2+a3+a4 つまりisの確率、 1isa1/sの確率、...2a2/s

次に、 を使用してランダムな double d を作成しgenerator.nextDouble()ます。

0 <= d < a1/s整数が 1 の場合、

その場合a1/s <= d < (a1+a2)/s、整数は 2 でなければなりません

その場合(a1+a2)/s <= d < (a1+a2+a3)/s、整数は 3 でなければなりません

その場合(a1+a2+a3)/s <= d < 1、整数は 4 でなければなりません

于 2014-01-15T16:05:27.833 に答える