只是编写一个程序来洗牌一副牌,并根据RNG是在for循环的内部还是外部播种而得到不同的行为; 即
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会导致这种情况吗?
答案 0 :(得分:3)
如果你需要伪随机数,只需要一次种子。如果您多次调用srand并且如果在时钟种子更改之前执行此操作,那么您将获得相同的值而不是随机的。刚刚开始种子一次。您可以打开其他程序(winamp等..)以获得更多随机值(您需要减慢程序;)或者为随机迭代制作空循环可以修复第一个程序。但你需要非常大的随机数,如20亿(必须小于40亿))
答案 1 :(得分:3)
由于时间(NULL)仅每秒更改一次,因此如果for循环完成时间不超过一秒,则RNG种子将相同。
答案 2 :(得分:0)
虽然其他人完全正确,你不想在循环中使用srand(time(0)),因为你会得到较差的随机性,因为你重复设置相同的种子,你可能希望保持这是为了调试:如果您需要能够“重播”一个案例,请将种子写入日志文件并允许显式设置种子。否则,使用随机数调试应用程序可能相当棘手......
答案 3 :(得分:0)
你可以使用boost posix时间。
但是在所有情况下如果你只需要调用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;
}
问候