【问题标题】:Generating array of unique random numbers生成唯一随机数数组
【发布时间】:2019-03-12 12:43:10
【问题描述】:

我正在编写一个函数,该函数应该使用从 0 到 n 的随机数填充数组(其中 n 被传递给函数的参数),但数组中的所有数字都应该是唯一的。我基本上需要将数字数组从 0 改组到 n

我在这里找到了这个答案:Unique random numbers in an integer array in the C programming language

并使用了用户建议的“Knuth算法”:

void generate_random_array(int count)
{
  int in, im;

  im = 0;
  srand(time(NULL));

  for (in = 0; in < count && im < count; ++in) {
    int rn = count - in;
    int rm = count - im;
    if (rand() % rn < rm) random_array[im++] = in; 
  }
}

然而,这个函数根本不会为我生成随机数,它只是创建一个从 0 到计数的数字数组。如何生成唯一数字的实际随机序列。

【问题讨论】:

    标签: c random


    【解决方案1】:

    您引用的答案中的算法的C实现示例如下:

    #define M 10
    #define N 100
    
    int in, im;
    
    im = 0;
    
    for (in = 0; in < N && im < M; ++in) {
      int rn = N - in;
      int rm = M - im;
      if (rand() % rn < rm)    
        /* Take it */
        vektor[im++] = in + 1; /* +1 since your range begins from 1 */
    }
    

    Knuth 算法。这是一个非常简单的算法,复杂度为 O(N)(即数值范围),意味着当 M 接近 N 时它最有用。

    但是你设置的M == N 不接近,但是等于

    所以rnrm的初始值是一样的。所以这不能使算法正常工作,因为:

    whatever % rn < rm
    

    总是如此,就像345436 % 22 &lt; 22 一样,因为a % b &lt; b,总是如此。

    所以test总是为真,每次都存储整数,所以inim每次都加1,以此类推。

    我基本上需要将数字数组从 0 打乱到 n

    这个算法不是你所需要的:它根本不打乱一个数组,它通过不时地从增加的值中挑选一个来产生有序的随机数(所以,唯一的)。像您正在做的那样约束值会强制算法发出所有范围的值。

    Shuffle array in C 会带来更好的运气

    【讨论】:

    • 我意识到这可能是问题所在,但由于我想生成从 0 到 N 的 N 个数字,而不是从 0 到 M 的 N 个数字,我认为 N=M 会起作用。我需要使用其他算法吗?
    • 我已编辑。实际上,您只需要使用另一个问答。
    【解决方案2】:

    我基本上需要将数字数组从 0 打乱到 n

    那么为什么不do that? Knuth 算法用于选择指定的整个范围的随机子集,它按升序发出。 哪个子集是随机的,不是元素的顺序,而是只有一个子集包含所有个元素。在任何情况下,如果您希望它们以随机顺序排列,那么您仍然需要对 Knuth 算法的结果进行洗牌,这样您就可以准确地从起点开始。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-03
      • 2020-05-27
      • 1970-01-01
      • 1970-01-01
      • 2010-12-09
      • 2018-05-03
      相关资源
      最近更新 更多