【问题标题】:How to create a new random integer between a specif range如何在特定范围之间创建一个新的随机整数
【发布时间】:2012-11-08 07:50:10
【问题描述】:

我有一个从 1 到 100 的数字范围,它们是列表的索引,我需要随机选择一个列表。如果在列表中找不到我要查找的内容,我需要在使我进入列表的范围内选择下一个随机整数,它不应该是之前选择的那个,, 有一种方法可以在 C 中有效地做到这一点。我可以通过改组索引数组来做到这一点,但我想知道是否有更好的方法。

总而言之,我需要一个非常好的随机算法,它返回一个我知道是随机的并且以前从未使用过的整数。

我知道 rand()、srand() 和 randomize()。我不确定这些是否达到目的。

【问题讨论】:

    标签: c gcc random


    【解决方案1】:

    arc4random_uniform 可以解决问题,如果您的系统上可用的话:

    uint32_t r = 1U + arc4random_uniform(100); // r = 1...100
    

    如果您需要唯一编号,请从值数组开始并使用Fisher-Yates (aka Knuth) shuffle

    如果数组小于范围,您可以用唯一的随机数强制填充,然后随机播放 - 即如果您只需要 10 个数字,那么您可以在 大约 20 个随机数中生成它-gen 调用。请注意,只有在填充过程中也对其进行了排序(以便更快地查找匹配)时,才需要在这种情况下进行随机播放。

    另一种方法是填充向量 [1...100] 并从中随机抽取剩余元素,并在使用时删除条目。

    【讨论】:

    • Fisher-Yeates 解决方案是通往这里的道路。
    【解决方案2】:

    您可以将srandrandtime() 的知识与% 操作结合起来。
    % n - 在 n 上给出 除法提醒,这显然不能在 n 时更大。
    所以在代码方面:

    srand(time());
    int value = rand() % n; // will give you random values within interval [0,n)
    

    但我需要提到 rand() 有一些缺点,其中之一是它不提供均匀分布,因为较低值的概率较高(您可以找到与此主题相关的讨论在stackoverflow上)

    【讨论】:

    • 参见例如eternallyconfuzzled.com/arts/jsw_art_rand.aspx 为什么这通常不是一个好的建议,我不得不 -1 这个因为你暗示你知道你的解决方案很糟糕但仍然传播它。
    • 我不同意你的观点,我建议使用 % 操作,它可以与任何随机数生成技术相结合,当然不限于 。我还指出了 rand() 的一些缺点。
    • @spin_eight:但是你没有提到% 运算符的真正缺点,如果n 不能均匀地划分RAND_MAX,它会给结果增加偏差。
    • @Archie 我不知道,你能给我解释一下在这种情况下出现的偏见,或者对解释的来源提供一些参考吗?
    • @spin_eight 在 SO 上看到这个问题:stackoverflow.com/questions/10984974/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-24
    • 2021-09-17
    • 2016-01-03
    • 1970-01-01
    • 2015-07-02
    • 2021-06-22
    • 1970-01-01
    相关资源
    最近更新 更多