2

只需编写一个程序来洗牌,并根据 RNG 是在 for 循环内部还是外部播种而得到不同的行为;IE。

  for(int i = 0; i < 52; i++)
{
  srand(time(0));  
  Card temp = deck[i];
  int toSwap = rand()%52;
  deck[i] = deck[toSwap];
  deck[toSwap] = temp;
}

给出输出

Nine of Hearts
Ace of Clubs
Two of Clubs
Three of Clubs
Four of Clubs

等等,但是

void DeckOfCards::shuffle()
{
  srand(time(0));  
  for(int i = 0; i < 52; i++)
  {
  Card temp = deck[i];
  int toSwap = rand()%52;
  deck[i] = deck[toSwap];
  deck[toSwap] = temp;
  }
  currentCard =0;
}

导致

Ace of Hearts
Queen of Spades
Four of Hearts
Seven of Clubs
Five of Hearts

(正确的功能)。任何人都知道为什么重新播种 RNG 会导致这种情况?

4

4 回答 4

3

如果您需要伪随机数,则只需要一次种子。如果您多次调用 srand 并且在时钟种子更改之前执行此操作,那么您将获得相同的值而不是随机值。一开始只播种一次。您可以打开其他程序(winamp 等)以获得更多随机值(您需要减慢程序速度;)或者为随机迭代制作空循环可以修复第一个程序。但是您需要非常大的随机数,例如 20 亿(必须小于 40 亿))

于 2012-07-18T15:03:19.673 回答
3

由于 time(NULL) 仅每秒更改一次,因此如果 for 循环完成时间不超过一秒,RNG 种子将是相同的。

于 2012-07-18T15:04:52.980 回答
0

虽然其他人是完全正确的,你不想在循环中使用 srand(time(0)) 因为你会得到很差的随机性,因为你重复设置相同的种子,你可能希望记住这一点用于调试:如果您需要能够“重播”一个案例,请将种子写入日志文件并允许显式设置种子。否则使用随机数调试应用程序可能会相当棘手......

于 2012-07-18T15:44:23.023 回答
0

您可以改用 boost posix time。

但在所有情况下,如果您只需要调用 srand 两次,则可以使用两个不同的固定值。

或者,我使用此函数以毫秒为单位获取时间

 inline long
    getTimeMs ()
    {
      struct timeval start;
      long mtime;

      gettimeofday (&start, NULL);

      mtime = ((start.tv_sec) * 1000 + start.tv_usec / 1000.0) + 0.5;

      return mtime;
    }

问候

于 2012-07-18T15:53:29.827 回答