如何控制选号的概率?

How to control the probability of picking a number?

我正在制作一个游戏,我想在 0n 之间选择一个随机数,我想让选择一个更大的数字的机会更少。

所以我问了 question, and based on ,我写了这个:

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 会影响选取两个不同值之间的机会比率,而主要思想将保持不变:选取更高的值会更难。

这样可以吗?如果你使用加法版本,你最终会得到相同的概率。我正在使用更新的乘法版本。

此外,使用 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;
    }
}