首页 文章

理解“随机性”

提问于
浏览
825

我不能理解这个,这是更随机的?

rand()

要么

rand() * rand()

我发现它是一个真正的脑筋急转弯,你能帮助我吗?

EDIT:

直觉上我知道数学答案将是它们同样随机,但我不禁想到,如果你将两者相乘的话“运行随机数算法”两次,那么你将创造一些比随机更随机的东西它一次 .

28 回答

  • 9

    “随机”与“更随机”有点像要求哪个零更零 .

    在这种情况下, rand 是PRNG,因此不是完全随机的 . (事实上,如果种子已知,则可以预测) . 将它乘以另一个值使其不再或多或少随机 .

    真正的加密型RNG实际上是随机的 . 通过任何类型的函数运行值都不能为它添加更多的熵,并且可能很可能删除熵,使其不再随机 .

  • 151

    只是澄清一下

    虽然每当您尝试发现伪随机变量或其乘法的随机性时,前面的答案是正确的,但您应该知道,虽然 Random() 通常是均匀分布的,但 Random() * Random() 不是 .

    示例

    这是通过伪随机变量模拟的uniform random distribution sample

    Histogram of Random()

    BarChart[BinCounts[RandomReal[{0, 1}, 50000], 0.01]]
    

    虽然这是在将两个随机变量相乘后得到的分布:

    Histogram of Random() * Random()

    BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] * 
                                     RandomReal[{0, 1}, 50000], {50000}], 0.01]]
    

    所以,两者都是“随机的”,但它们的分布却截然不同 .

    另一个例子

    虽然 2 * Random() 是均匀分布的:

    Histogram of 2 * Random()

    BarChart[BinCounts[2 * RandomReal[{0, 1}, 50000], 0.01]]
    

    Random() + Random() is not!

    Histogram of Random() + Random()

    BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] + 
                                     RandomReal[{0, 1}, 50000], {50000}], 0.01]]
    

    中心极限定理

    The Central Limit Theorem states that the sum of Random() tends to a normal distribution as terms increase.

    只需四个学期:

    Histogram of Random() + Random() + Random() + Random()

    BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] + RandomReal[{0, 1}, 50000] +
                       Table[RandomReal[{0, 1}, 50000] + RandomReal[{0, 1}, 50000],
                       {50000}],
             0.01]]
    

    在这里,您可以通过将1,2,4,6,10和20个均匀分布的随机变量相加来看到从均匀到正态分布的道路:

    Histogram of different numbers of random variables added

    Edit

    一些学分

    感谢Thomas Ahle在评论中指出最后两幅图像中显示的概率分布被称为Irwin-Hall distribution

    感谢Heike为她的精彩torn[] function

  • 53

    我猜两种方法都是随机的,虽然我的gutfeel会说 rand() * rand() 随机性较小,因为它会播种更多的零 . 一旦 rand()0 ,总数就变为 0

  • 1469

    两者都不是“更随机” .

    rand() 基于伪随机种子生成可预测的数字集(通常基于当前时间,总是在变化) . 将序列中的两个连续数字相乘可生成不同但同样可预测的数字序列 .

    解决这是否会减少碰撞,答案是否定的 . 它实际上会增加碰撞,因为两个数字乘以 0 < n < 1 的效果 . 结果将是较小的分数,导致结果偏向光谱的下端 .

    一些进一步的解释 . 在下文中,“不可预测的”和“随机的”是指某人根据先前的数字猜测下一个数字的能力,即 . 一个神谕 .

    给定种子 x ,它生成以下值列表:

    0.3, 0.6, 0.2, 0.4, 0.8, 0.1, 0.7, 0.3, ...
    

    rand() 将生成以上列表, rand() * rand() 将生成:

    0.18, 0.08, 0.08, 0.21, ...
    

    两种方法总是为同一种子生成相同的数字列表,因此可以通过oracle同样预测 . 但是如果你看两个调用相乘的结果,你会看到它们都在 0.3 下,尽管在原始序列中分布不错 . 由于两个分数相乘的影响,这些数字是有偏见的 . 由此产生的数字总是较小,因此尽管仍然不可预测,但更有可能是碰撞 .

  • 13

    Oversimplification to illustrate a point.

    假设您的随机函数仅输出 01 .

    random()(0,1) 之一,但 random()*random()(0,0,0,1) 之一

    您可以清楚地看到,在第二种情况下获得 0 的机会绝不等于获得 1 的机会 .


    当我第一次发布这个答案时,我希望尽可能地保持这个答案,以便阅读它的人能够一目了然地了解 random()random()*random() 之间的区别,但我无法回答原来的广告问题:

    Which is more random?

    由于 random()random()*random()random()+random()(random()+1)/2 或任何其他不会导致固定结果的组合具有相同的熵源(或者在伪随机生成器的情况下具有相同的初始状态),答案是它们是相同的随机(差异在于它们的分布) . 我们可以看到的一个完美的例子是Craps游戏 . 你获得的数字将是 random(1,6)+random(1,6) 并且我们都知道获得7的机会最高,但这并不意味着滚动两个骰子的结果或多或少比滚动结果的结果更随机 .

  • 12

    这是一个简单的答案 . 考虑垄断 . 你滚动两个六面骰子(或者对于那些喜欢游戏符号的人来说是2d6)并拿走它们的总和 . 最常见的结果是7,因为有6种可能的方法可以滚动7(1,6 2,5 3,4 4,3 5,2和6,1) . 而2只能在1,1上滚动 . 很容易看出滚动2d6与滚动1d12不同,即使范围相同(忽略你可以在1d12上得到1,这个点保持不变) . 将结果相乘而不是添加结果会使它们以类似的方式偏斜,大部分结果都会出现在范围的中间 . 如果你正在努力为了减少异常值,这是一个很好的方法,但它无助于均匀分布 .

    (奇怪的是它也会增加低滚动 . 假设你的随机性从0开始,你会看到一个0的尖峰,因为它会将其他滚动变为0 . 考虑0和1之间的两个随机数(包括0)如果任一结果为0,则无论其他结果如何,整个事物都变为0 . 获得1的唯一方法是两个卷都是1.在实践中这可能无关紧要但这会产生一个奇怪的图表 . )

  • 81

    强制xkcd ......

    return 4; // chosen by fair dice roll, guaranteed to be random.

  • 67

    可能有助于以更离散的数字来考虑这一点 . 考虑想要生成1到36之间的随机数,因此您决定最简单的方法是投掷两个公平的6面骰子 . 你得到这个:

    1    2    3    4    5    6
      -----------------------------
    1|   1    2    3    4    5    6
    2|   2    4    6    8   10   12
    3|   3    6    9   12   15   18
    4|   4    8   12   16   20   24   
    5|   5   10   15   20   25   30
    6|   6   12   18   24   30   36
    

    所以我们有36个数字,但并非所有数字都被公平表示,有些根本没有出现 . 中心对角线附近的数字(左下角到右上角)将以最高频率出现 .

    描述骰子之间不公平分布的相同原则同样适用于0.0到1.0之间的浮点数 .

  • 26

    关于“随机性”的一些事情是违反直觉的 .

    假设 rand() 平缓分布,以下内容将为您提供非平坦分布:

    • 偏见偏好: sqrt(rand(range^2))

    • 偏见在中间达到峰值: (rand(range) + rand(range))/2

    • 低:偏见: range - sqrt(rand(range^2))

    还有很多其他方法可以创建特定的偏差曲线 . 我对 rand() * rand() 进行了快速测试,它会让你获得非常非线性的分布 .

  • 79

    大多数rand()实现都有一段时间 . 即经过一些大量的调用后,序列重复出现 . rand() * rand() 的输出序列在一半的时间内重复,因此在这个意义上它是"less random" .

    而且,如果不仔细构造,对随机值执行算术往往会导致较少的随机性 . 上面的海报引用了“ rand() rand() rand() ...”(k次,比如说),实际上往往是k值的范围值的平均值 rand() 返回 . (这是一个随机游走,步骤对称的意思 . )

    假设你的rand()函数返回范围为[0,1)的均匀分布的随机实数的具体性 . (是的,这个例子允许无限精确 . 这赢得了't change the outcome.) You didn' t选择一种特定的语言,不同的语言可能做不同的事情,但以下分析适用于任何非反常的rand()实现的修改 . 产品 rand() * rand() 也在范围[0,1)但不再均匀分布 . 实际上,该产品可能在区间[0,1 / 4]中与区间[1 / 4,1]中的区间一样 . 更多的乘法会使结果进一步偏向零 . 这使得结果更具可预测性 . 从广义上看,更可预测= =更少随机 .

    几乎任何关于均匀随机输入的操作序列将是非均匀随机的,从而导致可预测性增加 . 小心,人们可以克服这个属性,但是在你真正想要的范围内生成一个均匀分布的随机数会更容易,而不是浪费算术时间 .

  • 23

    你正在寻找的概念是“熵”,即一串比特无序的“程度” . 根据“最大熵”的概念,这个想法最容易理解 .

    具有最大熵的比特串的近似定义是它不能精确地用较短的比特串表示(即,使用一些算法将较小的字符串扩展回原始字符串) .

    最大熵与随机性的相关性源于这样一个事实,即如果你选择一个“随机”数字,你几乎肯定会选择一个其位串接近于具有最大熵的数字,也就是说,它不能被压缩 . 这是我们对“随机”数字特征的最佳理解 .

    因此,如果你想从随机的两个随机样本中随机抽取一个随机数,你可以将两个位串连接在一起 . 实际上,您只需将样本填充到双倍长度字的高低两半 .

    从更实际的角度来说,如果你发现自己背负着一个蹩脚的兰德(),它有时可以帮助将几个样本合在一起---但是,如果它真的被打破,即使这个程序也无济于事 .

  • 7

    接受的答案非常可爱,但还有另一种方法可以回答你的问题 . PachydermPuncher's answer已经采用了这种替代方法,我只想稍微扩展一下 .

    该思考信息理论的最简单方法是根据最小的信息单位,一点点 .

    在C标准库中, rand() 返回0到 RAND_MAX 范围内的整数,这个限制可能根据平台的不同而定义 . 假设 RAND_MAX 恰好被定义为 2^n - 1 ,其中 n 是某个整数(在Microsoft的实现中恰好是这种情况,其中 n 是15) . 然后我们会说一个好的实现会返回 n 位信息 .

    想象一下, rand() 通过翻转硬币来找到一位的值来构造随机数,然后重复直到它有一批15位 . 然后这些位是独立的(任何一位的值不影响同一批中其他位的具有特定值的可能性) . 因此,独立考虑的每个位都像0到1之间的随机数,并且在该范围内是"evenly distributed"(可能为0为1) .

    比特的独立性确保了由批量比特表示的数字也将在其范围内均匀分布 . 这是直观明显的:如果有15位,则允许的范围为零到 2^15 - 1 = 32767.该范围内的每个数字都是唯一的位模式,例如:

    010110101110010
    

    如果这些位是独立的,则没有模式比任何其他模式更可能发生 . 因此,范围内的所有可能数字都是可能的 . 反之亦然:如果 rand() 产生均匀分布的整数,则这些数字由独立位组成 .

    因此,将 rand() 视为制造钻头的 生产环境 线,恰好可以按任意尺寸批量 生产环境 . 如果您不喜欢这个尺寸,请将批次分成几个部分,然后将它们放回到您喜欢的任何数量(尽管如果您需要的特定范围不是2的幂,您需要缩小数字到目前为止,最简单的方法是转换为浮点数) .

    回到你原来的建议,假设你想从15批到30批,请求 rand() 为第一个数字,将它移位15位,然后再添加 rand() . 这是一种将两个调用组合到 rand() 而不会影响均匀分布的方法 . 它的工作原理很简单,因为放置信息位的位置之间没有重叠 .

    这与"stretching" rand() 的范围乘以常数非常不同 . 例如,如果你想将 rand() 的范围加倍,你可以乘以2 - 但现在你'd only ever get even numbers, and never odd numbers! That'并不是一个平滑的分布,并且可能是一个严重的问题,具体取决于应用程序,例如:一个类似轮盘赌的游戏,据说允许奇数/偶数投注 . (通过考虑比特,你可以意识到乘以2与将位向左移位(更大的重要性)一个位置并用零填充间隙是相同的 . 所以显然信息量是相同的 - 它只是移动了一点 . )

    数值范围中的这种间隙在浮点数应用中是无法控制的,因为浮点范围本身具有根本无法表示的间隙:在每两个可表示浮动之间的间隙中存在无限数量的缺失实数点数!因此,无论如何,我们必须学会忍受差距 .

    正如其他人所警告的那样,直觉在这个领域是有风险的,特别是因为数学家无法抵抗实数的诱惑,实际数字是充满了粗糙无限和明显悖论的可怕混乱 .

    但至少如果你认为它的位数,你的直觉可能会让你更进一步 . 比特非常简单 - 即使是计算机也可以理解它们 .

  • -1

    正如其他人所说,简单的简单回答是:不,它不是更随机,但确实会改变分布 .

    假设你正在玩骰子游戏 . 你有一些完全公平,随意的骰子 . 如果在每次掷骰子之前,你首先将两个骰子放入一个碗中,摇晃它,随机挑选一个骰子,然后滚动那个骰子,那么模具辊是否会“更随机”?显然它没有任何区别 . 如果两个骰子都给出随机数,那么随机选择两个骰子中的一个将没有任何区别 . 无论哪种方式,你都会获得1到6之间的随机数,并且在足够数量的卷上均匀分布 .

    我想在现实生活中,如果您怀疑骰子可能不公平,这样的程序可能会有用 . 例如,如果骰子略微不 balancer ,那么一个人往往比1/6时间更频繁地给出1个,而另一个往往经常给出6个,然后在两者之间随机选择会倾向于模糊偏见 . (虽然在这种情况下,1和6仍然会超过2,3,4和5.嗯,我想这取决于不 balancer 的性质 . )

    随机性有很多定义 . 随机序列的一个定义是它是由随机过程产生的一系列数字 . 通过这个定义,如果我掷了5次模具,得到数字2,4,3,2,5,这是一个随机系列 . 如果我再滚动相同的公平模具5次并获得1,1,1,1,1,那么这也是一个随机系列 .

    几张海报指出,计算机上的随机函数不是真正随机的,而是伪随机的,如果你知道算法和种子它们是完全可预测的 . 这是事实,但大多数时候完全无关紧要 . 如果我将一副纸牌洗牌,然后一次转过一张,这应该是一个随机的系列 . 如果有人偷看卡片,结果将是完全可预测的,但是通过大多数随机性的定义,这不会使其随机性降低 . 如果该系列通过随机性的统计测试,我偷看卡片的事实将不会改变这一事实 . 在实践中,如果我们在你猜猜下一张牌的能力上赌大笔钱,那么你偷看牌的事实是非常重要的 . 如果我们使用该系列来模拟我们网站访问者的菜单选择以测试系统的性能,那么您偷看的事实将完全没有任何区别 . (只要您不修改程序以利用这些知识 . )

    EDIT

    我不认为我可以将我对Monty Hall问题的回答写成评论,所以我会更新我的答案 .

    对于那些没有读过Belisarius链接的人来说,它的要点是:一个游戏节目选手可以选择3个门 . 在一个人的背后是一个有 Value 的奖品,在其他人背后是一些毫无 Value 他选择了#1门 . 在揭示它是胜利者还是失败者之前,主持人打开了#3门,表明它是一个失败者 . 然后,他让参赛者有机会转到#2门 . 参赛者应该这样做吗?

    答案,冒犯了许多人的直觉,是他应该转换 . 他的原始选秀权是获胜者的概率是1/3,另一扇门是赢家的概率是2/3 . 我最初的直觉,以及许多其他人的直觉,是切换没有收获,赔率刚刚变为50:50 .

    毕竟,假设有人在主人打开失败之门后打开电视 . 那个人会看到两个关门 . 假设他知道游戏的性质,他会说每个门有1/2的机会隐藏奖品 . Spectator 的赔率如何是1/2:1/2,而参赛者的赔率是1/3:2/3?

    我真的不得不考虑这个来打败我的直觉 . 要掌握它,请理解当我们谈论这样的问题中的概率时,我们的意思是,给定可用信息的概率 . 对于将奖品放在门后的工作人员,比如门#1,奖品在门#1后面的概率是100%,并且它落后于其他两个门的可能性为零 .

    机组成员的赔率与参赛者的赔率不同,因为他知道参赛者没有的东西,即他把奖品放在哪一扇门上 . 同样地,竞赛者的赔率与 Spectator 的赔率不同,因为他知道 Spectator 没有的东西,即他最初选择的门 . 这并非无关紧要,因为主持人选择打开哪扇门并非随意 . 他不会打开选手挑选的门,也不会打开隐藏奖品的门 . 如果这些是同一扇门,那么他就有两个选择 . 如果它们是不同的门,则只留下一个 .

    那么我们如何提出1/3和2/3呢?当参赛者最初选择一扇门时,他有1/3的机会挑选胜利者 . 我认为这很明显 . 这意味着有2/3的机会,其中一个门是赢家 . 如果主持人为他提供切换机会而不提供任何其他信息,那么就没有收获 . 再次,这应该是显而易见的 . 但是看待它的一种方法是说他有2/3的机会通过转换获胜 . 但他有两种选择 . 所以每个人只有2/3除以2 = 1/3的机会成为赢家,这并不比他原来的选择更好 . 当然我们已经知道最终结果,这只是以不同的方式计算它 .

    但现在主持人透露,这两个选择中的一个不是赢家 . 因此,他没有选择的一个门的2/3几率是胜利者,他现在知道2个替代品中有1个不是它 . 另一个可能是也可能不是 . 所以他不再有2/3分开2.他打开门为零,闭门为2/3 .

  • -1

    考虑到你有一个简单的硬币翻转问题,即使被认为是头,奇数被认为是尾巴 . 逻辑实现是:

    rand() mod 2
    

    在足够大的分布上,偶数的数量应该等于奇数的数量 .

    现在考虑稍微调整一下:

    rand() * rand() mod 2
    

    如果其中一个结果是偶数,那么整个结果应该是均匀的 . 考虑4种可能的结果(偶数偶数=偶数,偶数奇数=偶数,奇数偶数=偶数,奇数奇数=奇数) . 现在,在足够大的分布上,答案应该是75%的时间 .

    如果我是你,我会打赌 .

    这个注释实际上更多地解释了为什么你不应该基于你的方法实现自定义随机函数,而不是讨论随机性的数学属性 .

  • 34

    如果对随机数组合会发生什么有疑问,您可以使用您在统计理论中学到的经验教训 .

    在OP的情况下,他想知道X * X = X ^ 2的结果是什么,其中X是沿均匀[0,1]分布的随机变量 . 我们将使用CDF技术,因为它只是一对一的映射 .

    由于X~Uniform [0,1]它的cdf是:fX(x)= 1我们想要变换Y < - X ^ 2因此y = x ^ 2找到逆x(y):sqrt(y)= x this给出x作为y的函数 . 接下来,求导数dx / dy:d / dy(sqrt(y))= 1 /(2 sqrt(y))

    Y的分布如下:fY(y)= fX(x(y))| dx / dy | = 1 /(2 sqrt(y))

    我们还没有完成,我们必须得到Y的域 . 因为0 <= x <1,0 <= x ^ 2 <1所以Y在[0,1]范围内 . 如果你想检查Y的pdf是否确实是pdf,请将其整合到域中:Integrate 1/(2 sqrt(y)) from 0 to 1实际上,它会弹出为1.另外,请注意所述函数的形状看起来像belisarious发布的那样 .

    至于X1 X2 ...... Xn,(其中Xi~Uniform [0,1]),我们可以诉诸于中心极限定理,该定理适用于任何存在时刻的分布 . 这就是Z测试实际存在的原因 .

    用于确定结果pdf的其他技术包括雅可比变换(其是cdf技术的通用版本)和MGF技术 .

    编辑:作为澄清,请注意我所说的结果转换的分布而不是随机性 . 那更为复杂,在任何情况下都不会导致任何种类的均匀分布 .

  • 23

    这并不是很明显,但 rand() 通常比 rand()*rand() 更随机 . 对于大多数用途来说,实际上非常重要 .

    但首先,它们会产生不同的分布 . 如果这是你想要的,这不是问题,但它确实很重要 . 如果您需要特定的分布,那么忽略整个“哪个更随机”的问题 . 那么为什么 rand() 更随机?

    rand() 为什么更随机的核心(假设它产生范围为[0..1]的浮点随机数,这是非常常见的)是当你将两个FP数乘以大量信息时尾数,你最后会得到一些信息丢失;因为你(可能)并不真正重要的是你产生哪种分布(即,你用来进行组合的操作),所以_760385这么重要 . 这些随机数中的每一个具有(最多)52比特的随机信息 - 该数据仍然限于具有最多52比特的随机信息 .

    大多数随机数的使用甚至没有使用随机源中实际可用的随机性 . 获得一个好的PRNG,不要太担心它 . (“善”的级别取决于你正在做什么;在进行蒙特卡罗模拟或加密时你必须要小心,否则你可以使用标准的PRNG,因为它通常要快得多 . )

  • 3

    浮动随机数通常基于生成0到某个范围之间的整数的算法 . 因此,通过使用rand()* rand(),您实际上是在说int_rand()* int_rand()/ rand_max ^ 2 - 意味着您要排除任何素数/ rand_max ^ 2 .

    这显着改变了随机分布 .

    rand()在大多数系统上均匀分布,如果播种得当,很难预测 . 使用它,除非您有特殊的理由对其进行数学运算(即,将分布整形为所需的曲线) .

  • 1

    根据您的计算机体系结构,乘以数字将最终处于较小的解决方案范围内 .

    如果您的计算机显示器显示16位 rand() 将被称为0.1234567890123乘以秒 rand() ,0.1234567890123,则会给出0.0152415这样的东西'd definitely find fewer solutions if you' d重复实验10 ^ 14次 .

  • 10

    大多数这些分布都是因为您必须限制或标准化随机数 .

    我们将其标准化为全部正,适合范围,甚至适合指定变量类型的内存大小约束 .

    换句话说,因为我们必须限制0和X之间的随机调用(X是我们变量的大小限制),我们将有一组介于0和X之间的“随机”数字 .

    现在,当您将随机数添加到另一个随机数时,总和将介于0和2X之间...这会使值偏离边缘点(将两个小数字加在一起的概率和两个大数字在一起时非常小你有两个大范围的随机数) .

    想想你有一个接近于零的数字并添加它的情况使用另一个随机数时,它肯定会变得更大并且远离0(对于大数字也是如此,并且随机函数返回的两个大数字(接近X的数字)不太可能两次 .

    现在,如果您要设置具有负数和正数的随机方法(跨越零轴平均跨越),则不再是这种情况 .

    比方说 RandomReal({-x, x}, 50000, .01) 那么你会在负面积极的情况下获得均匀的数字分布,如果你要将随机数加在一起,他们会维持"randomness" .

    现在我不确定 Random() * Random() 会发生什么情况会发生负面到正面的 Span ......这将是一个有趣的图表......但我现在必须回到编写代码 . :-P

  • 19
    • 没有更随机的东西 . 它是随机的还是非随机的 . 随机意味着"hard to predict" . 这并不意味着非确定性 . 如果random()是随机的,random()和random()* random()都是随机的 . 就随机性而言,分布是无关紧要的 . 如果发生非均匀分布,则仅表示某些值比其他值更可能;他们仍然无法预测 .

    • 由于涉及伪随机性,因此数字非常具有确定性 . 然而,伪随机性在概率模型和模拟中通常是足够的 . 众所周知,使伪随机数发生器复杂化只会使分析变得困难 . 它不太可能改善随机性;它经常导致统计测试失败 .

    • 随机数的期望属性很重要:重复性和再现性,统计随机性,(通常)均匀分布,大周期是少数 .

    • 关于随机数的变换:正如有人所说,两个或多个均匀分布的总和导致正态分布 . 这是加性中心极限定理 . 只要所有分布都是独立且相同的,它就适用于源分布 . 乘法中心极限定理表示两个或多个独立和非均匀分布的随机变量的乘积是对数正态的 . 其他人创建的图形看起来是指数的,但它确实是对数正态的 . 因此random()* random()是对数正态分布的(尽管它可能不是独立的,因为数字是从同一个流中提取的) . 在某些应用中这可能是合乎需要的 . 但是,通常最好生成一个随机数并将其转换为对数正态分布数 . Random()* random()可能难以分析 .

    有关更多信息,请参阅我的书籍www.performorama.org . 这本书正在建设中,但有相关资料 . 请注意,章节和章节编号可能会随时间而变化 . 第8章(概率论) - 第8.3.1和8.3.3节,第10章(随机数) .

  • 11

    我们可以通过使用_760395来比较关于随机性的两个数字数组 . 如果数字序列不能被压缩,那么它是我们在这个长度上可以达到的最随机...我知道这种类型的测量更像是理论选择...

  • 1

    实际上,当你想到它 rand() * rand()less 随机而不是 rand() . 这就是原因 .

    基本上,奇数与偶数相同 . 并且说0.04325是奇数,并且像0.388是偶数,0.4是偶数,0.15是奇数,

    这意味着 rand()equal chance of being an even or odd decimal .

    另一方面, rand() * rand() 的赔率有点不同 . 让我们说:

    double a = rand();
    double b = rand();
    double c = a * b;
    

    ab 都有50%的偶数或奇数的概率 . 知道

    • 偶数*偶数=偶数

    • 偶数*奇数=偶数

    • 奇数*奇数=奇数

    • 奇数*偶数=偶数

    意味着 75% chancec 是偶数,而只有 25% chance 它是奇数,使得 rand() * rand() 的值比 rand() 更可预测,因此随机性更小 .

  • 7

    使用实现原始多项式的线性反馈移位寄存器(LFSR) .

    结果将是2 ^ n个伪随机数的序列,即在序列中没有重复,其中n是LFSR中的比特数....导致均匀分布 .

    http://en.wikipedia.org/wiki/Linear_feedback_shift_register http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf

    使用基于计算机时钟微量的“随机”种子,或者可能是文件系统中某些不断变化的数据的md5结果的子集 .

    例如,32位LFSR将从给定种子开始按顺序生成2 ^ 32个唯一数字(不相同) . 序列将始终处于相同的顺序,但起点对于不同的种子将是不同的(显然) . 因此,如果种子之间可能重复的序列不是问题,这可能是一个不错的选择 .

    我使用128位LFSR在硬件模拟器中使用种子生成随机测试,种子是不断变化的系统数据的md5结果 .

  • -2

    假设 rand() 返回一个数字在 [0, 1) 之间很明显 rand() * rand() 将偏向0 . 这是因为 x 乘以 [0, 1) 之间的数字将导致数字小于 x . 这是10000多个随机数的分布:

    google.charts.load("current", { packages: ["corechart"] });
    google.charts.setOnLoadCallback(drawChart);
    
    function drawChart() {
      var i;
      var randomNumbers = [];
      for (i = 0; i < 10000; i++) {
        randomNumbers.push(Math.random() * Math.random());
      }
      var chart = new google.visualization.Histogram(document.getElementById("chart-1"));
      var data = new google.visualization.DataTable();
      data.addColumn("number", "Value");
      randomNumbers.forEach(function(randomNumber) {
        data.addRow([randomNumber]);
      });
      chart.draw(data, {
        title: randomNumbers.length + " rand() * rand() values between [0, 1)",
        legend: { position: "none" }
      });
    }
    
    <script src="https://www.gstatic.com/charts/loader.js"></script>
    
    <div id="chart-1" style="height: 500px">Generating chart...</div>
    

    如果 rand() 返回 [x, y] 之间的整数,那么您将得到以下分布 . 注意奇数与偶数值的数量:

    google.charts.load("current", { packages: ["corechart"] });
    google.charts.setOnLoadCallback(drawChart);
    document.querySelector("#draw-chart").addEventListener("click", drawChart);
    
    function randomInt(min, max) {
      return Math.floor(Math.random() * (max - min + 1)) + min;
    }
    
    function drawChart() {
      var min = Number(document.querySelector("#rand-min").value);
      var max = Number(document.querySelector("#rand-max").value);
      if (min >= max) {
        return;
      }
      var i;
      var randomNumbers = [];
      for (i = 0; i < 10000; i++) {
        randomNumbers.push(randomInt(min, max) * randomInt(min, max));
      }
      var chart = new google.visualization.Histogram(document.getElementById("chart-1"));
      var data = new google.visualization.DataTable();
      data.addColumn("number", "Value");
      randomNumbers.forEach(function(randomNumber) {
        data.addRow([randomNumber]);
      });
      chart.draw(data, {
        title: randomNumbers.length + " rand() * rand() values between [" + min + ", " + max + "]",
        legend: { position: "none" },
        histogram: { bucketSize: 1 }
      });
    }
    
    <script src="https://www.gstatic.com/charts/loader.js"></script>
    
    <input type="number" id="rand-min" value="0" min="0" max="10">
    <input type="number" id="rand-max" value="9" min="0" max="10">
    <input type="button" id="draw-chart" value="Apply">
    
    <div id="chart-1" style="height: 500px">Generating chart...</div>
    
  • 2

    好的,所以我会尝试通过说你正在创建和使用随机数生成器来添加一些值来补充其他答案 .

    随机数生成器是具有多个特征的设备(在一般意义上),可以修改这些特征以适合目的 . 他们中的一些人(来自我)是:

    • 熵:如香农熵

    • 分布:统计分布(泊松,正常等)

    • 类型:应用数字的来源(算法,自然事件,组合等)和算法 .

    • 效率:执行的快速性或复杂性 .

    • 模式:周期性,序列,运行等 .

    • 可能更多......

    在这里的大多数答案中,分布是主要关注点,但是通过混合和匹配函数和参数,您可以创建生成随机数的新方法,这些随机数具有不同的特征,其中一些特征乍一看评估可能不明显 .

  • 0

    很容易证明两个随机数的总和不一定是随机的 . 想象一下,你有一个6面模具和滚动 . 每个数字都有1/6出现的机会 . 现在说你有2个骰子并总结了结果 . 这些总和的分布不是1/12 . 为什么?因为某些数字比其他数字更多 . 它们有多个partitions . 例如,数字2是仅1 1的总和,但是7可以由3 4或4 3或5 2等形成...因此它有更大的可能性 .

    因此,应用变换,在这种情况下,对随机函数的加法不会使其更随机,或者必然保持随机性 . 在上面的骰子的情况下,分布倾向于7,因此随机性较小 .

  • 0

    正如其他人已经指出的那样,这个问题是 hard to answer ,因为我们每个人都有他的头脑 .

    这就是为什么,我强烈建议您花点时间阅读本网站以更好地了解随机性:

    回到真正的问题 . 这个术语中没有或多或少的随机:

    both only appears random

    在这两种情况下 - 只是rand()或rand()* rand() - 情况是相同的:经过数十亿的数字序列 will repeat(!) . 它对观察者来说是随机的,因为他不知道整个序列,但计算机却有 no true random source - 所以他也不能产生随机性 .

    e.g.: Is the weather random? 我们没有足够的传感器或知识来确定天气是否随机 .

  • -1

    答案取决于它,希望rand()* rand()比rand()更随机,但是:

    • 两个答案取决于您的值的位大小

    • 在大多数情况下,你生成的取决于伪随机算法(它主要是一个数字生成器,它取决于你的计算机时钟,而不是那么随机) .

    • 使你的代码更具可读性(而不是用这种口头禅来调用一些随意的伏都教神) .

    好吧,如果您检查以上任何一项,我建议您选择简单的"rand()" . 因为你的代码会更多 readable (不会问你自己为什么写这个,因为...好......超过2秒),易于维护(如果你想用super_rand替换你的rand函数) .

    如果你想要一个更好的随机,我建议你从任何提供足够噪音(无线电静电)的源流,然后一个简单的 rand() 就足够了 .

相关问题