【问题标题】:Unbalanced random number generator不平衡随机数发生器
【发布时间】:2011-12-13 07:50:15
【问题描述】:

我必须从升序数组中选择一个元素。较小的元素被认为更好。因此,如果我从数组的开头选择一个元素,它被认为是一个更好的选择。但同时我不希望选择是确定性的并且总是相同的元素。所以我在找

产生范围 [0, n] 内的数字的随机数生成器,但是 数字越小,产生的机会就越大。

我想到了:

num = n;
while(/*the more iteration the more chance for smaller numbers*/)
  num = rand()%num;

我想知道是否有人有更好的解决方案。
我确实看过一些类似的问题,但它们一般都有关于随机数生成的详细信息。我正在寻找这种特定类型的随机数生成的解决方案,无论是算法还是提供它的库。

【问题讨论】:

标签: c++ c random


【解决方案1】:

[0,n) 之间生成一个随机数,比如x,然后在[0,1] 之间生成另一​​个随机浮点数,比如y。然后将 x 提高到 y 的幂并使用 floor 函数,您将得到您的数字。

int cust(int n)
{
  int x;
  double y, temp;
  x = rand() % n;
  y = (double)rand()/(double)RAND_MAX;
  temp = pow((double) x, y);
  temp = floor(temp);
  return (int)temp;
}

更新:以下是调用上述函数 10 次的一些示例结果,其中 n = 10、20 和 30。

2 5 1 0 1 0 1 4 1 0

1 2 4 1 1 2 3 5 17 6

1 19 2 1 2 20 5 1 6 6

【讨论】:

  • 谢谢,这可能有用,但是有一个问题:如何在 C++ 中生成 [0,1] 范围内的数字? (rand()%n)/(float)n?
  • 0到n的数:(double)rand() / ((double)RAND_MAX * n)
  • @AtoMerZ- 这将产生高概率的随机数。
  • 再次感谢。这似乎是一个更好的解决方案,因为它只调用 rand() 一次。我会等待更多答案,如果没有更好的答案,我会接受。
  • 请注意,无论n如何,n - 1 平均每个RAND_MAX 试验只会发生一次,这可能比您想要的要小得多(RAND_MAX2**31-1 在我的机,或约 20 亿)。您可能希望研究解决这种急剧下降的方法。
【解决方案2】:

我想到的简单临时方法是使用标准随机生成器,但重复索引。所以在数组中:

0, 0, 0, 1, 1, 2, 3

采用较小元素的可能性很大。
我不知道你到底需要什么。您还可以定义自己的分布,或者使用一些随机数生成库。但建议的方法简单且易于配置。
UPDATE2:您不必显式生成数组。对于大小为 1000 的数组,您可以从区间 [0,1000000] 生成随机数,然后配置您自己的选定值分布:例如,长度为 1200 的区间用于较小的值 (0-500),长度为 800 的区间用于较大的值(500-1000)。主要的一点是这样你可以很容易地配置概率并且你不必重新实现随机数生成器。

【讨论】:

  • 如果我的数组中有 1000 个数字,您提供的内容几乎不可能实现。
  • 数组只是一个例子。要点是更改较小值的间隔。请参阅更新 2。
  • 这是迄今为止实现非均匀分布(尤其是加权分布)的最佳解决方案。它需要最少的计算时间并提供完全的灵活性。
  • 那么更大的间隔 = 更多的机会?
  • +1 谢谢,总的来说这是一个很好的解决方案,但我认为对于这种特殊情况,我的更简单,需要的配置更少。
【解决方案3】:

使用适当的随机分布,例如exponential distribution 的四舍五入结果。选择一个适合您需求的发行版,记录您使用的发行版,然后找到一个不错的实现。如果可以选择 GNU 公共许可证下的代码,请使用出色的 GNU Scientific Library (GSL),或尝试 Boost.Random。

【讨论】:

  • 我很确定我了解 Boost.Random。还有什么?
  • @AtoMerZ:我扩展了首字母缩略词。
【解决方案4】:

两个工具将解决许多随机​​分布需求

1) 你拥有的统一随机数生成器

2) 以及将统一值映射到目标分布的函数

我现在得去城里了,但我回来后会记下一些例子和一张图。

在这个related question中讨论了一些有价值的方法和想法(更多关于生成正常的伪随机数)

【讨论】:

    猜你喜欢
    • 2011-01-23
    • 2019-07-18
    • 2019-12-15
    相关资源
    最近更新 更多