-1

在浏览了一段时间的问题并在谷歌上搜索了一堆之后,我发现自己很痛苦,因为没有一个“随机”生成器是真正随机的,我所说的随机是什么意思?总随机性,我在编译它们并运行多次打印大量值后发现的所有算法,结果是相同的,或者至少可以找到一种模式。这很糟糕,我正在为 MMO 服务器做一个随机数生成器,其功能将从升级项目到将一组玩家分成团队,模式总是,总是不好,想象每次我重新启动程序时生成相同的数字顺序。我的想法是,获得随机数的最好方法是弄乱时间,你永远无法知道某事发生的确切时间,如果时间非常精确就更好了。

inline __int64 NanoTime()
{
    struct { int low, high; } Nano;

    __asm push EAX
    __asm push EDX
    __asm __emit 0fh __asm __emit 031h
    __asm mov Nano.low, EAX
    __asm mov Nano.high, EDX
    __asm pop EDX
    __asm pop EAX

    return *(__int64 *)( &Nano );

}

static DWORD g_Prev = NanoTime();

__int64 xRandom( void )
{
    __int64 Now = NanoTime() - g_Prev / 2;
    CString strRand, strLast;
    strRand.Format( "%I64d", Now );
    strLast = strRand.GetAt( strRand.GetLength()-1 );
    strLast += strRand.GetAt( strRand.GetLength()-2 );
    return( atoi( strLast ) );
}

虽然文本很大,但问题很简单,我需要一个尽可能小的算法的实数生成器的方向,我的解决方案每秒被调用数十万次不是我想要的,它只是在这里提示我需要的方向。

我已经研究过boost,比如不使用最低位顺序time(0)等。但都有一个模式。

4

1 回答 1

5

我在编译它们并运行多次打印大量值后发现的所有算法,结果是相同的,或者至少可以找到一种模式。

坦率地说,听起来您尝试过的算法很差,或者您使用或评估它们的方式并不理想。

如果标准rand()还不够(这是一个很大的假设!),你最好的选择是更高级别的伪随机生成器,例如Mersenne Twister。此类算法已被证明可以通过各种统计随机性测试。

如果你要选择你使用的硬件,最近的(Ivy Bridge)英特尔硬件提供了一个带有内置熵源的片上随机数生成器:RDRAND. 这提供了良好的随机性和高吞吐量,但对于您的需求来说可能是多余的。

想象每次我重新启动程序时都会生成相同的数字顺序

如果这是一个问题,听起来你没有正确地为你的生成器播种。如果你每次运行一次,并使用当前时间作为种子,你将在不同的运行中得到不同的随机序列。

我想出了一个很棒的解决方案。

如果我正确阅读了您的代码,则您的熵源是TSCmodulo 100。试着在一个紧密的循环中调用你的生成器,看看它到底有多随机。

于 2012-12-18T23:14:34.163 回答