如何控制选择数字的概率?

时间:2015-06-07 23:28:09

标签: java algorithm math probability

我正在建立一个游戏,我想在0n之间选择一个随机数,我想让选择一个更高的数字会有更低的机会。

所以我问了this问题,基于amit answer,我写了这个问题:

public class Test {
    private static Random random = new Random();

    public static void main(String[] ars) {
        int n = 30;
        float x = 5f;

        int[] results = new int[n];
        for (float i = 1; i <= 10000; i++) {
            int choose = pickANumber(n, x);
            results[choose]++;
        }
        for (int i = 0; i < results.length; i++) {
            System.out.println(i + "\t" + results[i]);
        }
    }

    static int pickANumber(int n, float x) {
        ArrayList<Float> values = new ArrayList<>();
        n += 2;
        for (float i = 2; i < n; i++) {
            float value = i * (i - 1) / (2f * x);
            values.add(value);
        }
        float max = ((n - 1) * (n - 2) / (2 * x));
        return pickANumber(max, values);
    }

    static int pickANumber(float max, ArrayList<Float> values) {
        float number = random.nextFloat() * max;
        int i = Collections.binarySearch(values, number);
        if (i < 0) {
            i = i * -1 - 1;
        }
        return i;
    }
}

输出我用10,000次运行选择每个数字的时间。

0   22
1   47
2   59
3   95
4   109
5   142
6   127
7   175
8   188
9   224
10  243
11  249
12  270
13  268
14  340
15  356
16  362
17  345
18  444
19  430
20  469
21  479
22  495
23  493
24  522
25  583
26  587
27  597
28  648
29  632

问题是我选择x的值是什么并不重要,我总是得到相同的输出。

我需要找到一种方法来修复此算法,因此x会影响拾取两个不同值之间的机会比例,而主要想法仍然存在:拾取更高的值会更难。

1 个答案:

答案 0 :(得分:1)

这样可以吗?如果您使用添加剂版本,您将始终拥有相同的概率。我正在使用更新的乘法版本。

此外,使用x<1可以降低获得更高值的机会。否则x>1

import java.util.Arrays;
import java.util.Random;

public class Main {
    private static Random random = new Random();

    public static void main(String[] ars) {
        int n = 30;
        double x = 0.9;

        double[] aux = makeAux(n, x);
        int[] results = new int[n];
        for (float i = 1; i <= 10000; i++) {
            results[pickANumber(aux)]++;
        }
        for (int i = 0; i < results.length; i++) {
            System.out.println(i + "\t" + results[i]);
        }
    }

    static double[] makeAux(int n, double x) {
        double[] aux = new double[n];
        aux[0] = x;
        for (int i = 1; i < n; i++)
            aux[i] = aux[i - 1] + Math.pow(x, (i + 1));
        return aux;
    }

    static int pickANumber(double[] aux) {
        double number = random.nextDouble() * aux[aux.length - 1];
        int i = Arrays.binarySearch(aux, number);
        if (i < 0)
            i = -i - 1;
        return i;
    }
}