【问题标题】:How to model random variables?如何建模随机变量?
【发布时间】:2017-07-11 01:01:49
【问题描述】:

我想知道如何使用“基本操作”对随机变量进行建模。我知道的唯一随机函数,至少对于 C,是 rand(),以及用于播种的 srand。在线某处可能存在软件包,但可以说我想自己实现它。不知道有没有其他很常见的随机函数,如果没有,还是坚持rand()和C语言吧。

rand() 允许我从0RAND_MAX 伪随机生成int。然后我可以使用mod 在某个范围内获得int。接下来我可以mod 2 选择一个符号并获得负数。我也可以使用rand()/RAND_MAX 对区间(0,1) 中的值进行建模,并将其转换为模型Uniform(a,b)

但我不确定是否可以将其扩展为对任何概率分布进行建模,以及在什么时候我必须担心准确性,尤其是在处理无穷大和非理性概率时。另外,这个方法很粗糙,所以我想知道更多使用基本工具的标准方法。

一个简单的例子:

我有随机变量X,这样Pr(X = 1)=1/piPr(X=0)=1-1/pi。由于pi 是非理性的,我会用rand() 近似得到1/pi 的概率,如果我从0Round(RAND_MAX*1/pi) 得到int,则选择X=1。所以这大约是两次,一次用于pi,另一次用于舍入。

有没有更好的方法?如何对更复杂的东西进行建模,例如在区间(0,infinity) 上的连续随机变量或在可数无限集上具有非理性概率的离散随机变量。我的方法是否仍然有效,还是我必须担心舍入错误?

编辑:另外,rand() 的伪随机性而不是随机性如何改变事物,我将如何解释这些变化?

【问题讨论】:

  • “然后我可以使用 mod 获取某个范围内的 int。” 不。您必须除法,而不是使用 mod,因为您只会使用随机性较小的低位。
  • @spectras 不保证rand 的质量。因此,没有指定低位或高位是否“更随机”。事实上,如果您需要任何类型的真正随机分布,rand 是不可行的。哦,除非输入范围是除数的整数倍,否则 div 和 mod 都不合适。
  • 我觉得这个问题或多或少值得一讲,作为它的答案。这没有错,并且有过这样的讲座的史诗案例,但它也(字面上)提出了很多要求。 :)
  • @olaf> 虽然你是对的,但在很多情况下,你通过除法获得的质量或多或少是可以接受的,而使用改装绝对不是。比如,小范围内的随机整数,比如 {0, 1, 2}。修改可以让您获得 [½, ¼, ¼] 的概率。划分不会完美,但仍然更接近 [⅓, ⅓, ⅓]。足够接近,您可以接受它,具体取决于用例。
  • @KamiKaze:我只是想添加一些信息(确实可以是unsigned int,只是带有正的int 范围)。您的其余评论都很好。

标签: c random probability


【解决方案1】:

然后我可以使用 mod 获取某个范围内的 int

不,你不能。用骰子试试。你想要一个介于 1 和 5 之间的数字。所以你选择 roll mod 5(有点,它实际上是 ((roll-1)%5)+1)。这将 1 映射到 1、2 映射到 2 等等。5 映射到 5 和 6 映射到 1。您现在有 1 的可能性是任何其他滚动的两倍。

这样做的正确方法是找到比您的范围高的最近的 2 次方,屏蔽掉高于 2 次方的随机数位,然后检查您是否在范围内。如果您不在范围内,请再试一次(可能会永远循环,实际上平均重试次数少于 2 次)。这假设您的随机数是比特流而不是其他东西。对于体面的生成器来说,这通常是一个安全的假设。

我也可以使用 rand()/RAND_MAX 对区间 (0,1) 中的值进行建模

不,你不能。这不是浮点数的工作方式。这会产生可怕的分布。

要么整数中的位数小于尾数中的位数,那么你就会得到一堆你永远无法生成的浮点数。或者整数中的位数大于尾数中的位数,然后在除法之前将整数转换为浮点数时会截断整数,并且会更频繁地生成某些数字。

在区间 (0,1) 中并将其转移到模型 Uniform(a,b)。

这让事情变得更糟。首先你在一个方向丢失比特,然后你在另一个方向丢失比特。

在任意范围内实际生成均匀分布的浮点数比看起来要难。

几年前我自己做了一些实验来解决这个问题,在这个过程中学习了浮点内部原理,我在这里用大量 cmets 编写了一些代码:https://github.com/art4711/random-double

简而言之,要在任意范围内生成随机浮点数:找到该范围内较大的绝对值。那是开始,范围的另一端是结束。从头到尾找出下一个可表示的数字。从开始减去下一个数字,这成为步骤。计算开始和结束之间存在多少步。在 0 和步数之间生成一个均匀分布的随机数。 start + step * 随机数就是答案。此外,由于浮点的工作方式,这可能不是您想要的。使用此方法肯定不可能生成所有可能的浮点值(非常特殊的情况除外)。但是这种方法保证了每一个可能的值都是等可能的。

请注意,您的误解很常见。几乎每个人都会做这些事情。行业中的随机数绝不是随机的。计算机科学中的随机一词几乎意味着“可预测的、可重复的、容易破解和可利用的,很可能分布不均”。不要让我开始了解标准库中“随机”数字生成器的质量。如果你翻遍我的 github 资料,你会发现一个 Go 的包,里面有很长的 README 咆哮。

我不会回答你剩下的问题,这些部分需要一两本书。

【讨论】:

  • @domoremath 不是真的。这只是我多年来编写代码和与加密货币人(痴迷于好的随机数)交往所收集的知识。出发点是认识到仅仅因为我们使用运算符+-*/ 并不意味着它们的行为就像在真正的数学中一样。尤其是浮点数。剩下的就是阅读标准和文档以了解实际情况。
猜你喜欢
  • 1970-01-01
  • 2021-06-03
  • 2014-02-23
  • 1970-01-01
  • 2015-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-04
相关资源
最近更新 更多