【问题标题】:Is there a random number generator which can skip/drop N draws in O(1)?是否有一个随机数生成器可以在 O(1) 中跳过/丢弃 N 个抽奖?
【发布时间】:2019-06-26 08:06:33
【问题描述】:

是否有任何(非加密)伪随机数生成器可以在 O(1) 或 O(log N) 但小于 O(N) 时跳过/丢弃 N 个抽奖。


特别是对于并行应用程序,拥有上述类型的生成器将是有利的。要生成随机数数组的图像。可以为此任务编写一个并行程序,并为每个线程独立地播种随机数生成器。但是,数组中的数字将与顺序情况不同(可能除了前半部分)。

如果存在上述类型的随机数生成器,则第一个线程可以使用用于顺序实现的种子作为种子。第二个线程也可以用这个种子播种,然后丢弃/跳过由第一个线程生成的 N/2 个样本。然后输出数组将与串行情况相同(易于测试),但仍会在更短的时间内生成。 下面是一些伪代码。

#define _POSIX_C_SOURCE 1
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>

void rand_r_skip(unsigned int *p_seed, int N)
{
    /* Stupid O(N) Implementation */
    for (int i = 0; i < N; i++)
    {
        rand_r(p_seed);
    }
}

int main()
{
    int N = 1000000;
    unsigned int seed = 1234;
    int *arr = (int *)malloc(sizeof(int) * N);

#pragma omp parallel firstprivate(N, seed, arr) num_threads(2)
    {
        if (omp_get_thread_num() == 1)
        {
            // skip the samples, obviously doesn't exist
            rand_r_skip(&seed, N / 2);
        }
#pragma omp for schedule(static)
        for (int i = 0; i < N; i++)
        {
            arr[i] = rand_r(&seed);
        }
    }
    return 0;
}

非常感谢大家的帮助。我确实知道可能有证据表明这样的生成器不能同时存在并且是“伪随机”的。我非常感谢有关在哪里可以找到更多信息的任何提示。

【问题讨论】:

  • 明显的候选者是计数器模式下的任何对称密码。
  • @ChrisDodd:是的,跳过 O(1)。当然,生成相对昂贵,除非您将密码缩减到仅几轮。
  • 感谢您的 cmets。

标签: random


【解决方案1】:

克里斯·多德写道:

明显的候选者是计数器模式下的任何对称密码。

【讨论】:

    【解决方案2】:

    正如 Severin Pappadeux 所指出的,PCG variant developed by M.E. O'NeillCC++Haskell 实现为此类向前跳跃/向后跳跃提供了一个接口 功能:herein

    函数名称为:advancebackstep,分别简要记录了 hereathereat

    引自网页(在撰写本文时访问):

    ... 随机数生成器就像一本书,逐页列出统计随机数。种子为我们提供了一个起点,但有时能够在序列中向前或向后移动并且能够高效地这样做很有用。

    PCG 生成方案的 C++ 实现提供了高效向前跳转和向后高效跳转的前进。

    【讨论】:

      【解决方案3】:

      当然。 Linear Conguential Generator 及其后代可以在 O(log(N)) 时间跳过 N 数字的生成。它基于 F.Brown 的论文,link

      Here 是这个想法的实现,C++11。

      【讨论】:

      • 感谢您的快速回复。
      • @LukasKoestler 不客气。请记住,LCG 被认为不是高质量的 RNG。但是基于 LCG 的 RNG 质量更好——我相信 PCG——共享这种 O(log(N)) 的跳跃能力。 pcg-random.org
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-14
      • 2016-11-01
      • 2011-06-26
      • 1970-01-01
      • 1970-01-01
      • 2018-04-26
      • 2015-11-17
      相关资源
      最近更新 更多