【问题标题】:Repeated random number in a loop循环中的重复随机数
【发布时间】:2011-06-14 13:29:46
【问题描述】:

需要为每个不同的循环生成 0 到 1 之间的随机数。

for ( 1 to 10000)调用RandomKey函数生成不同的随机数。 但问题是每次迭代我都会得到相同的数字。

RandomKey函数如下:

 void RandomKey ()
 {
   srand((unsigned)time(0));
   for (int k=0;k<ActivityNumber;k++)
 {

Act_num[k].Priority=(rand()%10000)*0.0001;//random number

 }


for (int i=0;i<ActivityNumber;i++)
   arr[i]=Act_num[i].Priority;

我该如何解决这个问题?

【问题讨论】:

  • 您系统上的RAND_MAX 是什么?
  • 优先级为浮动。 Rand_max 我不知道。但问题出在srand
  • 记住:如果你在函数 RandomKey() 中将种子设置为 time(0),如果调用是在同一时间,你会通过 rand() 得到相同的数字(分辨率为 1 秒)
  • @furkan:说清楚一点;你是说调用RandomKey()时,arr[0]arr[1]等的值都是一样的?即arr[0] == arr[1]等?或者你的意思是arr[0]重复 调用RandomKey() 时总是相同的?
  • @furkan: 另请注意,(float)rand() / (float)RAND_MAX 是获得 0 到 1 之间均匀分布值的更简洁的方法。

标签: c++


【解决方案1】:

将种子函数调用 (srand) 移到函数调用之外(即,在程序的开头,一次)。

编辑:进一步思考,如果你的意思是你在 arr 中得到全 0(如果是说...int),那是因为 rand()%10000)*0.0001 返回一个介于 0 和 0.0003 左右的数字,所以如果你将它们转换为int,你会得到0。

Edit2:没关系,看来我第一次猜对了:)

【讨论】:

  • 虽然不是 srand 应该使用的方式,但我不认为这是代码失败的原因。
  • @Blindy:为什么srand 的位置会影响循环的各个迭代中的值?
  • 另外,(rand()%10000)*0.0001 是否应该返回 0 或 1 真的很可疑。相反,我会做 (int) rand() &amp; 1 或类似的事情来获得均匀分布的零和一。
  • @Oli,我假设他说错了,意味着他在重复调用该函数时获得了相同的值。如果我是对的,我们很快就会看到:)
  • @Blindy:如果这就是 OP 的意思,那么我会同意你的看法。但是仅仅将它移到函数调用之外并不能解决这个问题。他需要的是单个呼叫srand
【解决方案2】:

由于处理器速度很快,time(0) 也一样。只拨打一次srand

【讨论】:

  • 好的。我在主函数中调用它,并且只调用一次。结果是一样的。我调用我的 RandomKey 函数,并且在每个迭代数组中 arr 具有相同的值。
  • @furkan:那么请更新您的问题以显示您的新代码。
【解决方案3】:

(我在这里重申其他建议。)

您至少应该验证三件事:

  • 只在你的程序中调用srand一次
  • 如果srand 被多次调用,或者您的程序每秒运行多次,则do not use time(0) to initialize srand
  • 如果每个随机数只能是 0 或 1,则应调用 (int)(rand() &amp; 1) 以获取从零到一的均匀分布数。如果您需要 floats 介于 0.0 和 1.0 之间,则需要采用不同的方式。

编辑:如果您只想要一个介于零和一之间的随机浮点数,请参阅Generating random number between [-1, 1] in C?

【讨论】:

  • 也许我无法清楚地描述问题。每次调用 RandomKey 函数时,我都需要 0 到 1 之间的随机数。也就是说,我在 arr[] btw 1 和 0 中需要 n 个数字,并且每次迭代都需要 arr[] 并且需要不同的值。例如;在第一次迭代中,我得到 arr[0]=0.0021,arr[1]=0.3245.......,毕竟我再次调用我的函数,我得到 arr[0]=0.0021,arr[1]=0.3245等等。我做了你上面提到的,但问题没有改变
  • 是的。我得到数字,但每个循环我得到相同的数字
  • @furkan:同样,如果您不向我们展示您的新代码,我们只能猜测问题所在。请编辑您的问题!
【解决方案4】:

在程序运行的整个过程中,您应该调用 srand() 一次,并且只调用一次。

实际上,您根本不应该调用它,因为 srand()/rand() 在许多机器上完全被破坏了。 C++0x 终于修复了这个问题。如果您可以使用 Boost 或 TR1,则可以立即使用新的和改进的 C++ 随机数,而不必等到 C++0x 最终成为标准,然后再等待供应商实现它的时间更长。

其他替代方案(尽管没有一个是标准的一部分)是 srandom()/random() 和 srand48()/drand48()。后者,如果可用,形成一个很好的简单界面。 drand48() 产生一个介于 0 和 1 之间的随机双精度数。或者自己滚动。 任何东西都比 rand() 好。

【讨论】:

    【解决方案5】:

    为我工作:

    但是当您发布代码时,您应该发布可编译的代码(否则我们只是在猜测)。此外,通过使代码足够小以在此处发布,您通常会发现您犯的愚蠢错误:

    #include <time.h>
    #include <stdlib.h>
    
    #include <algorithm>
    #include <iterator>
    #include <iostream>
    
    int const iterationnumber = 5;
    int const ActivityNumber  = 5;
    
    double arr[5];                          // HERE is probably your mistake (double not int)
    struct { double Priority; } Act_num[5]; // OR HERE make sure Priority is a double
    
    void RandomKey();
    int main ()
    {
        srand((unsigned)time(0));
    
        for (int k=0;k<iterationnumber;k++)
        {
            RandomKey ();//i call randomkey for every iteration
    
            std::copy(&arr[0], &arr[ActivityNumber], std::ostream_iterator<double>(std::cout, " "));
            std::cout << "\n";
        }
    }
    
    void RandomKey ()
    {
        for (int k=0;k<ActivityNumber;k++)
        {
            Act_num[k].Priority=(rand()%10000)*0.0001;//random number
        }
    
        for (int i=0;i<ActivityNumber;i++)
            arr[i] = Act_num[i].Priority;
    }
    

    【讨论】:

      【解决方案6】:

      此代码只生成一次唯一的随机数。

      #include <ctime>
      # include <iostream>
      using namespace std;
      
      
      int main()
      {
      
            int size=100;
            int random_once[100];
            srand(time(0));
      
            for (int i=0;i<size;i++)  // generate unique random number only once
            {
                random_once[i]=rand() % size;
                for(int j=0;j<i;j++) if (random_once[j]==random_once[i]) i--;   
            }
      
            for ( i=0;i<size;i++) cout<<" "<<random_once[i]<<"\t";
      
        return 0;
      

      【讨论】:

        猜你喜欢
        • 2011-03-04
        • 1970-01-01
        • 1970-01-01
        • 2013-08-16
        • 1970-01-01
        • 2013-05-02
        • 2014-01-19
        • 1970-01-01
        相关资源
        最近更新 更多