【问题标题】:How to generate different random numbers in a loop in C++?如何在 C++ 的循环中生成不同的随机数?
【发布时间】:2011-06-23 00:49:40
【问题描述】:

是否可以在每次循环运行时生成不同的随机数。例如,我有:

for (int t=0;t<10;t++)
{
    int random_x;
    srand ( time(NULL) );
    random_x = rand() % 100;
    cout<<"\nRandom X = "<<random_x;
} 

但问题是,它每次都会生成相同的随机数。是否可以在每次循环运行时生成不同的随机数?

是否也有可能重置随机数初始化?

【问题讨论】:

标签: c++ loops random


【解决方案1】:

不要在循环内使用srand,只使用一次,例如在main() 的开头。 srand() 正是你重置它的方式。

【讨论】:

  • 我这样做了,但它现在只更改一次随机值。例如它生成 15、23、23、23、23。现在我该怎么办?
  • 如果你真的把它放在 main() 的开头,你就不会得到那个序列。
  • 仍然如果你在秒内多次执行程序,随机数序列将是相同的
【解决方案2】:

您每次都得到相同的随机数,因为您在循环中设置了一个种子。即使您使用的是time(),它每秒只更改一次,因此如果您的循环在一秒钟内完成(很可能会),您每次都会获得相同的种子值和相同的初始随机数。

srand() 调用移出循环(并且只在应用开始时调用一次),您应该会得到随机的“随机”数字。

【讨论】:

  • 将它移到循环之外可能还不够,因为循环可能每秒被调用多次。
  • 我这样做了,但它现在只更改一次随机值。例如它生成 15、23、23、23、23。现在我该怎么办?
  • 另请注意,srand()rand() 相比非常昂贵。在 glibc 中,除了 srand() 完成的初始设置之外,它还调用 rand() 300 多次来搅拌锅。
  • 作为健全性检查,取下% 100 并查看rand 返回的原始值。使用% 运算符映射到一系列值可能会导致非正态分布,具体取决于所使用的RNG,因为低位可能不是完全随机的。更好的方法是执行val = min + (int) ((double) rand() / RAND_MAX * (max - min + 1); 之类的操作来映射到范围 [min,max]。
【解决方案3】:

不要不要使用rand();改用新的 C++11 工具(例如 std::mt19937std::uniform_int_distribution 等)。

您可以使用这样的代码 (live here on Ideone):

#include <iostream>
#include <random>
using namespace std;

int main()
{
    // Random seed
    random_device rd;

    // Initialize Mersenne Twister pseudo-random number generator
    mt19937 gen(rd());

    // Generate pseudo-random numbers
    // uniformly distributed in range (1, 100)
    uniform_int_distribution<> dis(1, 100);

    // Generate ten pseudo-random numbers
    for (int i = 0; i < 10; i++)
    {
        int randomX = dis(gen);
        cout << "\nRandom X = " << randomX;
    }
}

附言

考虑观看 Going Native 2013 会议的视频,了解有关rand() 相关问题的更多详细信息:

rand() Considered Harmful

【讨论】:

    【解决方案4】:

    尝试将种子 srand 移到循环之外,如下所示:

    srand ( time(NULL) );
    for (int t=0;t<10;t++)
    {
        int random_x;
        random_x = rand() % 100;
        cout<< "\nRandom X = "<<random_x;
    } 
    

    正如 Mark Ransom 在评论中所说,将种子移到循环之外只有在循环不驻留在您多次调用的函数中时才会有所帮助。

    【讨论】:

    • 将其移出循环可能还不够,因为循环可能每秒被调用多次。
    • 我这样做了,但它现在只更改一次随机值。例如它生成 15、23、23、23、23。现在我该怎么办?
    【解决方案5】:

    我有同样的问题好几天了。将 srand() 排除在循环之外是一个 +。另外,不要将 rand() % 100 分配给任何变量。只需 cout rand() % 100 在循环中。试试这个:

        srand (time(NULL));
        (int t=0;t<10;t++)
        {
        cout << rand() % 100 << endl;
        } 
    

    【讨论】:

      【解决方案6】:

      每次都停止为生成器播种。 将 srand 调用拉出循环

      【讨论】:

      • 我这样做了,但它现在只更改一次随机值。例如它生成 15、23、23、23、23。现在我该怎么办?
      • 你真的需要对每个答案都写相同的评论吗?
      【解决方案7】:

      srand 调用移动到程序的开头。正如您现在所拥有的,两次连续调用之间的时间可能相同,因此随机数生成器将在同一位置重新启动。

      【讨论】:

      • 我这样做了,但它现在只更改一次随机值。例如它生成 15、23、23、23、23。现在我该怎么办?
      【解决方案8】:

      你需要将 time() 的初始化从 for 循环中提取出来。

      这是一个示例,它将在 Windows 控制台中输出预期的 (ahah) 随机数。

      #include <iostream>
      #include <windows.h>
      #include "time.h"
      int main(int argc, char*argv[])
      {
          srand ( time(NULL) );
          for (int t = 0; t < 10; t++)
          {
              int random_x;
      
              random_x = rand() % 100;
              std::cout << "\nRandom X = " << random_x << std::endl;
          }
          Sleep(50000);
          return 0;
      }
      

      【讨论】:

      • 它说没有找到睡眠标识符
      • 您是否包含 windows.h ?这段代码在 VS2008 上对我来说很好。
      • 我用过这个,但它说“应用程序已请求运行时以不寻常的方式终止它
      • 要使用此代码在 Windows 控制台上获取数字,请务必将您的项目创建为“Win32 控制台应用程序”。然后,复制/粘贴此代码应该可以工作。
      • 它在“Win32 控制台应用程序”中运行,它运行了几个循环值,但它给出了错误。实际上我下面的代码也很长
      【解决方案9】:

      时间函数在循环的每次迭代中可能返回相同的值。

      尝试在循环之前初始化随机种子。

      【讨论】:

      • 我这样做了,但它现在只更改一次随机值。例如它生成 15、23、23、23、23。现在我该怎么办?
      【解决方案10】:

      每次迭代都会重置伪随机数序列,因为您使用相同的种子调用srand(因为对time 的调用非常频繁)。要么使用不同的种子,要么在进入循环之前调用srand一次

      【讨论】:

      • 我这样做了,但它现在只更改一次随机值。例如它生成 15、23、23、23、23。现在我该怎么办?
      【解决方案11】:
      /*this code is written in Turbo C++
       For Visual Studio, code is in comment*/
      
      int a[10],ct=0,x=10,y=10;    //x,y can be any value, but within the range of 
                                   //array declared
      randomize();                 //there is no need to use this Visual Studio
      for(int i=0;i<10;i++)
      {   a[i]=random(10);         //use a[i]=rand()%10 for Visual Studio
      }
      cout<<"\n\n";
      do
      {   ct=0;
          for(i=0;i<x;i++)
          {   for(int j=0;j<y;j++)
              {   if(a[i]==a[j]&&i!=j)
                  {   a[j]=random(10);    //use a[i]=rand()%10 for Visual Studio
                  }
                  else
                  {   ct++;
                  }
              }
          }
      }while(!(ct==(x*y)));
      

      嗯,我不是 C++ 专家,但在学校学过。在过去的 1 年里,我一直在使用这个算法将不同的随机值存储在一维数组中,但是经过一些更改后,这也可以在二维数组中使用。 欢迎对代码提出任何建议。

      【讨论】:

        【解决方案12】:

        函数rand() 的工作方式是每次调用它时,它都会生成一个随机数。在您的代码中,您调用过一次并将其存储到变量random_x 中。要获取所需的随机数而不是将其存储到变量中,只需像这样调用函数:

        for (int t=0;t<10;t++)
        {
            cout << "\nRandom X = " << rand() % 100;
        }
        

        【讨论】:

          【解决方案13】:

          不认识男人。在测试了 10 分钟等不同方式后,我找到了最适合我的方式。 (更改代码中的数字以获得大或小的随机数。)

              int x;
          srand ( time(NULL) );
          x = rand() % 1000 * rand() % 10000 ;
          cout<<x;
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-02-05
            • 1970-01-01
            • 1970-01-01
            • 2022-01-04
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多