当前位置: 首页 > 知识库问答 >
问题:

概率随机数

薛阳荣
2023-03-14

我想知道(例如在Java中)在特定范围内生成随机数的最佳方法是什么,其中每个数都有一定的发生概率?

e. g.

从[1;3]中生成概率如下的随机整数:

P(1)=0.2
P(2)=0.3
P(3)=0.5

现在,我正在考虑在[0;100]范围内生成一个随机整数的方法,并执行以下操作:

如果在[0; 20]以内--

共有3个答案

程俊健
2023-03-14

您已经在问题中编写了实现。;)

final int ran = myRandom.nextInt(100);
if (ran > 50) { return 3; }
else if (ran > 20) { return 2; } 
else { return 1; }

对于更复杂的实现,可以通过在如下开关表上计算结果来加快速度:

t[0] = 1; t[1] = 1; // ... one for each possible result
return t[ran];

但是,只有当这是一个性能瓶颈,并且每秒调用数百次时,才应该使用它。

毛越
2023-03-14

前段时间我写了一个helper类来解决这个问题,源代码应该把概念表现的足够清楚:

public class DistributedRandomNumberGenerator {

    private Map<Integer, Double> distribution;
    private double distSum;

    public DistributedRandomNumberGenerator() {
        distribution = new HashMap<>();
    }

    public void addNumber(int value, double distribution) {
        if (this.distribution.get(value) != null) {
            distSum -= this.distribution.get(value);
        }
        this.distribution.put(value, distribution);
        distSum += distribution;
    }

    public int getDistributedRandomNumber() {
        double rand = Math.random();
        double ratio = 1.0f / distSum;
        double tempDist = 0;
        for (Integer i : distribution.keySet()) {
            tempDist += distribution.get(i);
            if (rand / ratio <= tempDist) {
                return i;
            }
        }
        return 0;
    }

}

该类的用法如下:

DistributedRandomNumberGenerator drng = new DistributedRandomNumberGenerator();
drng.addNumber(1, 0.3d); // Adds the numerical value 1 with a probability of 0.3 (30%)
// [...] Add more values

int random = drng.getDistributedRandomNumber(); // Generate a random number

测试驱动程序以验证功能:

    public static void main(String[] args) {
        DistributedRandomNumberGenerator drng = new DistributedRandomNumberGenerator();
        drng.addNumber(1, 0.2d);
        drng.addNumber(2, 0.3d);
        drng.addNumber(3, 0.5d);

        int testCount = 1000000;

        HashMap<Integer, Double> test = new HashMap<>();

        for (int i = 0; i < testCount; i++) {
            int random = drng.getDistributedRandomNumber();
            test.put(random, (test.get(random) == null) ? (1d / testCount) : test.get(random) + 1d / testCount);
        }

        System.out.println(test.toString());
    }

此测试驱动程序的示例输出:

{1=0.20019100000017953, 2=0.2999349999988933, 3=0.4998739999935438}
司寇烨伟
2023-03-14

你的方法已经很好了,适用于任何范围。

想想:另一种可能性是通过乘以一个常数乘数来除掉分数,然后用这个乘数的大小建立一个数组。乘以10,你会得到

P(1) = 2
P(2) = 3
P(3) = 5

然后创建一个具有反数值的数组--“1”进入元素1和2,“2”进入元素3到6,依此类推:

P=(1,1,2,2,3,3,3,3);

然后你可以从这个数组中选择一个随机元素。

(添加。)使用kiruwka评论中例子中的概率:

int[] numsToGenerate           = new int[]    { 1,   2,    3,   4,    5   };
double[] discreteProbabilities = new double[] { 0.1, 0.25, 0.3, 0.25, 0.1 };

得出所有整数的最小乘数是20

2, 5, 6, 5, 2

因此,numsToGenerate的长度为20,其值如下:

1 1
2 2 2 2 2
3 3 3 3 3 3
4 4 4 4 4
5 5

分布是完全相同的:例如,“1”的几率现在是20分之2——仍然是0.1。

这是基于你最初的概率加起来是1。如果没有,将总数乘以相同的因子(也就是数组长度)。

 类似资料:
  • 问题内容: 我想知道在特定范围内生成随机数的最佳方法(例如在Java中)是什么,而每个范围内的每个数字都有一定的发生概率? 例如 从[1; 3]内产生随机整数,并具有以下概率: P(1)= 0.2 P(2)= 0.3 P(3)= 0.5 现在,我正在考虑在[0; 100]内生成随机整数并执行以下操作的方法: 如果它在[0; 20]之内->我得到我的随机数1。 如果它在[21; 50]之内->我得到

  • 我们了解了“样本空间”,“事件”,“概率”。样本空间中包含了一次实验所有可能的结果,事件是样本空间的一个子集,每个事件可以有一个发生的概率。概率是集合的一个“测度”。 这一讲,我们将讨论随机变量。随机变量(random variable)的本质是一个函数,是从样本空间的子集到实数的映射,将事件转换成一个数值。根据样本空间中的元素不同(即不同的实验结果),随机变量的值也将随机产生。可以说,随机变量是

  • 主要内容:实例,实例,概率分布,实例,实例,实例,实例,实例,实例,实例,数据分析,实例,实例,实例随机数 Verilog 中使用系统任务 $random(seed) 产生随机数,seed 为随机数种子。 seed 值不同,产生的随机数也不同。如果 seed 相同,产生的随机数也是一样的。 可以为 seed 赋初值,也可以忽略 seed 选项,seed 默认初始值为 0。 不使用 seed 选项和指定 seed 并对其修改来调用 $random 的代码如下所示: 实例     //seed va

  • 问题内容: 如何根据分配给每一行的概率机会从数据库中选择随机行。 例子: 如何根据必须选择的可能性来选择随机的品牌名称及其值。 和可以结合使用吗?如果是这样,最好的方法是什么? 问题答案: 您可以通过使用然后再使用累积和来执行此操作。假设它们的总和为100%: 笔记: 在子查询中被调用一次以初始化变量。多次调用是不可取的。 随机数极有可能恰好位于两个值之间的边界上。的任意选择1。 通过在时停止子查

  • 我正在尝试创建一个具有以下签名的函数: 它应做到以下几点: 生成从0到1的随机数,但不包括1 在该范围内选取任何给定数字的概率不是均匀分布的 选择的数字接近目标值的可能性更大(目标值也是从0到1的值) 概率曲线看起来像钟形曲线,目标值的概率最高,其周围的值逐渐变小,但0到1范围内的所有值仍有机会被选中。 这个机会的权重可以用概率值来调整,其中0表示没有对随机性施加权重,1表示几乎所有选择的数字都将

  • 随机变量的函数 在前面的文章中,我先将概率值分配给各个事件,得到事件的概率分布。 通过事件与随机变量的映射,让事件“数值化”,事件的概率值转移到随机变量上,获得随机变量的概率分布。 我们使用随机变量的函数,来定制新的随机变量。随机变量的函数是从旧有的随机变量到一个新随机变量的映射。通过函数的映射功能,原有随机变量对应新的随机变量。通过原有随机变量的概率分布,我们可以获知新随机变量的概率分布。事件,