Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 哪个C++;随机数引擎是否具有O(1)丢弃功能?_C++_C++11_Random_Complexity Theory - Fatal编程技术网

C++ 哪个C++;随机数引擎是否具有O(1)丢弃功能?

C++ 哪个C++;随机数引擎是否具有O(1)丢弃功能?,c++,c++11,random,complexity-theory,C++,C++11,Random,Complexity Theory,自C++11以来,有许多std随机数引擎。他们实现的成员函数之一是void discard(int long z),它跳过随机生成的z个数字。此函数的复杂性在www.cplusplus.com()上以O(z)表示 然而,在www.cppreference.com()上有一条注释说 对于某些引擎,“快速跳转”算法是已知的,它可以向前推进 不经计算,通过许多步骤(数以百万计)实现状态 中间状态转换 我如何知道哪些发动机的实际报废成本为O(1)?如果使用预计算的跳转点,O(1)将适用于存在的每个RNG

自C++11以来,有许多std随机数引擎。他们实现的成员函数之一是
void discard(int long z)
,它跳过随机生成的z个数字。此函数的复杂性在www.cplusplus.com()上以O(z)表示

然而,在www.cppreference.com()上有一条注释说

对于某些引擎,“快速跳转”算法是已知的,它可以向前推进 不经计算,通过许多步骤(数以百万计)实现状态 中间状态转换


我如何知道哪些发动机的实际报废成本为O(1)?

如果使用预计算的跳转点,O(1)将适用于存在的每个RNG。请记住,有些算法可能比O(z)更好,但不是O(1)-比如O(log2z)

如果我们谈论的是跳到任意点,事情就会变得有趣。例如,有一种已知的O(log2 z)提前跳转算法,它基于F.Brown的论文《任意步长随机数生成》,Trans。是Nucl。Soc。(1994年11月)。代码示例是

在C++11标准中有LCG RNG,不确定在特定实现中向前跳的速度有多快()


所有的RNG共享相同的属性,我认为根本不存在这样的东西。我的启发性结论是,
O(1)
-跳跃RNG基本上是一个散列,这意味着(例如,它可能根本不是“好的”RNG)

但是,即使您询问关于
O(logz)
的问题,我也看不到在STL中实现了这一点。 在GCC的
discard
函数中,我能够
grep
的所有函数都是简单的循环

      discard(unsigned long long __z)
      {
        for (; __z != 0ULL; --__z)
          (*this)();
      }
这不仅令人伤心,而且令人误解,因为只有在有有效方法的情况下,
discard
才应该存在

唯一重要的是
mersene
(如下),但它仍然是
O(z)

Boost的Mersenne有一个skip函数,但它只在大于(默认值)10000000(!?)的skip时调用。这已经告诉我跳过的计算非常繁重(即使是
O(logz)
)。

最后,信任显然对线性同余具有有效的
丢弃
,但仅在
c=0
的情况下。(我不确定这是否会降低它作为RNG的实用性。)
事实是,
std::linear\u conformential\u engine::discard(无符号长z)
绝对可以非常有效地实现。它主要相当于将
a
乘以
z
m
(对于零和非零
c
),这意味着大多数基本的软件实现都是在
O(log(z%phi(m))
UIntType
乘法(
phi(m))中执行的=m-1
表示素数和
您指的是哪本手册?我试过MSDN(),因为我在Visual Studio中工作,但没有找到答案。这没有帮助,因为函数没有正确的文档记录,所以我一直在做自己的基准测试?使用STL似乎有点费力。您可以查看源代码,它可以在Visual Studio安装指南中免费获得谢谢,是的。from我能看到的所有丢弃(z)函数都是使用for循环绘制z随机数来实现的,所以O(z)。不确定我是否忽略了什么。我可以补充一点,RNG算法将强烈地决定这有多可能。想象一下一种算法,它逐步通过一个预先计算的“随机”表通过已知步长值进行编号。在这种情况下,
表[(步长值*numSteps)%tableSize]
为O(1)。这是一个非常简单和有限的示例,但我在非常有限的系统上使用过类似的RNG方法,因此它在世界上占有一席之地。感谢您的回答。是的,我在寻找任意跳跃,而不是预先计算的跳跃。您链接到的PCG页面概述了原则上支持向前跳跃的引擎,优于O(z)。不过我真的很想知道O(1)。@alextack你让我想到了前跳的wrt O(1),我不确定这是否可能。基本上,应该有一个函数,其中有一个跳转值(比如说,64位)、状态值(XXX位)函数总是独立于跳转值进行相同数量的计算,以向前推进状态。可能不可能。您最好询问友好的mathexchange和/或交叉验证站点中是否存在此类RNG/函数。O(log2 z)对于me-30计算来说足够好,可以将RNG提高10亿。Blum-Blum-Shub也有这个特性,但在其他方面速度很慢。
    discard(unsigned long long __z)
    {
      while (__z > state_size - _M_p)
    {
      __z -= state_size - _M_p;
      _M_gen_rand();
    }
      _M_p += __z;
    }
void discard(unsigned long long __z)
{
    for (; __z != 0ULL; --__z)
        (*this)(); //<--  Wait what? Are you kidding me?
}