C ++随机数生成器:如何在每次执行时使数字随机

时间:2015-08-15 01:42:02

标签: c++ random

我不认为这是重复的,因为我已经尝试了其他SO答案,但它们对我不起作用。当我运行一个程序(随时间播种)时,我得到了一堆随机数。然后几秒钟后我再次运行程序并得到一组类似的随机数。

srand(time(0));
for(int i=0; i<10; i++) {
    cout<<rand()<<"\n";
}

8603 55 3146 26251 14799 16799 28230 314 3602 9504

8639 19984 3044 28803 29955 27225 29699 882 21389 7411

正如您所看到的,数字不同,但非常相似。这对我不起作用的原因是因为我将它转换为0到1之间的浮点数(除以RAND_MAX)。当我这样做时,以秒为单位的时间非常缓慢。一次运行我可以0.09245...然后我可以0.0925...。我正在使用这些概率制作二十一点AI,我不希望在后续执行中出现相同的投注模式。

我看了很多很多并尝试将种子放入循环中,但是只打印了10次相同的数字。不确定如何使数字从执行时间看起来完全随机。谢谢你的想法

编辑:

使用

    srand(rd());    
    for(int i=0; i<10; i++) {   
        cout<<generate()<<"\n";
    }

14514284786278117030 4620546740167642908 13109570281517897720 1746293864714​​8434322 355488278567739596 7469126240319926998 4635995468481642529 418970542659199878 9604170989252516556 6358044926049913402

每次运行它都会得到完全相同的序列。

编辑2:

一点点背景来消除困惑。我希望分发是均匀的,但如果不是这只是我自己的做法没有赌场业务。我原来的计划有6个字符,其值为12-20的命中/停留概率数组。所以像吉姆一样[0.958367,0.942123,0.876655,0.864322,0.7543321,0.653213,0.201201,0.12919,0.00001]将这些数字提高了。让我们说吉姆有一手14手。所以我得到一个0-1的随机数,如果它小于0.876655那么他就会命中。 100轮之后的获胜者将他们的“基因”混合在一起并且可能在1000个周期之后将自然地选择完美的孩子并且将形成完美的命中/通过比率。那就是为什么我注意到Pam或者总会有人打到:他们的随机数总是下降到0.05,所以无论她的手有多好或多坏,她都会打。我已经完成了,唯一的办法就是修复这个随机生成器以及另一个涉及投注金钱的小错误(我保证无关)

2 个答案:

答案 0 :(得分:6)

如果可能,请使用std::random_device获取种子,std::mt19937_64生成您的数字。 std::random_device旨在(但不幸的是,不保证)使用硬件生成真正的随机数,所以至少在一个好的实现中,它确实非常随机(但带宽相当低)。

C ++ 11呈现randsrand已经过时了。

这是一个非常简单的演示程序:

#include <random>
#include <iostream>

int main() { 

    std::mt19937_64 gen{ std::random_device()() };
    std::uniform_real_distribution<double> dis{ 0.0, 1.0 };

    for (int i=0; i<10; i++)
        std::cout << dis(gen) << "\n";
}

至少有了相当不错的库实现,这应该会产生相当可靠的结果。

答案 1 :(得分:1)

以下是我认为您希望它做的事情的一个例子:

//I'm guessing your time(0) was intended to be this?
static DWORD dwTime = timeGetTime();//static = value doesn't change
srand(dwTime);
while (1) //while the app is running, perform these actions.
{
    DWORD dwCurrTime = timeGetTime();
    for (int i = 0; i < 10; i++) {
        cout << rand() % 10 + 1 << "\n"; //1-10 
        //if dwTime + 500 milliseconds is less than current timeGetTime()
        //sleep, this allows you to check the code easily for repeats
        if (dwTime + 500 < dwCurrTime)
            Sleep(10000);
    }
}