5

我想生成2^300 到 2^10 范围内的随机数。我听说这个rand()函数不适合这么多数字。有没有其他方法可以生成几乎相等的分布?

4

6 回答 6

3

C++<random>库是一个很好的选择,有很多 PRNG 引擎和发行版可供选择。

#include <random>
#include <cstdint>
#include <iostream>

int main() {
    std::random_device r;
    std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
    std::mt19937_64 eng(seed);
    std::uniform_int_distribution<> dist(0, 1<<10);

    for (std::uint32_t i = 0; i< (1<<30); ++i) {
        int value = dist(eng);
        std::cout << value << ' ';
    }
}

此外,random_device 本身就是一个引擎,根据实现,它可以提供对非确定性或加密 RNG 的访问:

std::random_device eng;
std::cout << dist(eng) << '\n';

例如,在 libc++ 中它默认使用 /dev/urandom,在 OS X 上它使用 Yarrow 加密 RNG 算法。

于 2012-10-19T21:10:49.440 回答
2

在 Java 中,您可以使用 Random 在 2^48 个值之后重复。

Random rand = new Random();

for(int i = 0; i < (1<<30); i++) {
    int n = rand.nextInt(1 << 10);

}
于 2012-10-19T19:40:57.813 回答
1

g_random_int() 返回在 [0..2^32-1] 范围内均匀分布的随机 guint32。

#include <glib.h>

int
main(void)
{
     g_print("%d\n", g_random_int());
   return 0;
}

使用 gcc:

gcc -o rand rand.c `pkg-config --cflags --libs glib-2.0`

编辑:

直接从 /dev/random 读取(不太便携),像往常一样编译:

#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>

int
main(void)
{
    int             fd;
    unsigned int    number;

    fd = open("/dev/random", O_RDONLY);

    read(fd, &number, sizeof(number));

    printf("%u\n", number);
    close(fd);
  return 0;
}

PS:检查错误。

于 2012-10-19T23:32:20.693 回答
1

这是一个旧的 Usenet 帖子,其中包含许多有趣的 RNG - 所有这些都非常容易实现。

http://www.cse.yorku.ca/~oz/marsaglia-rng.html

它们可能与 Mersenne twister 不太匹配,但我已经很好地利用了其中的几个,它们肯定优于一些默认的 rand() 实现。它们通过了随机性的 DIEHARD 测试,其中包含的最大周期生成器的周期 > 2^7700 并且只需要几行即可实现。

于 2012-10-20T05:46:21.643 回答
0

Mark A. Overton于 2011 年 5 月 24 日在Dr. Dobbs上发表了一篇关于相当简单但高质量的 RNG 的好文章

于 2012-10-19T19:33:29.217 回答
0

增加随机性和周期的简单方法:

public class Random2 {

    private static int LEN = 64;
    private final int[] buf = new int[LEN];
    private Random r;
    private final int maxInt = 1 << 10;

    public Random2() {
        r = new Random();
        for (int i = 0; i < LEN; i++)
            buf[i] = r.nextInt(maxInt);
    }

    public int nextInt() {
        int i = r.nextInt(LEN);
        int x = buf[i];
        buf[i] = r.nextInt(maxInt);
        return x;
    }

}
于 2012-10-19T21:20:59.473 回答