【问题标题】:Generating Random number of 2^30生成 2^30 的随机数
【发布时间】:2012-10-19 19:21:34
【问题描述】:

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

【问题讨论】:

  • 查看 C++11 的 <random> 标头。
  • 在 C++03 中,Boost.Random(<random> 来自哪里)。
  • 生成均匀分布的大随机数不会有问题吗?
  • 认真的吗? java、c++ 和 c?您的问题是否与所有这些有关?
  • 其实任何语言都适合我,我只想重定向到文件!!如果是 C/C++,那么最好。

标签: java c++ c


【解决方案1】:

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 算法。

【讨论】:

  • 您使用的是什么编译器/库和版本?它可能还没有实现。您也可以尝试std::mt19937 或其他predefined random number generators 之一。
  • @john 你必须添加-std=c++0x 编译器选项
【解决方案2】:

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

Random rand = new Random();

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

}

【讨论】:

    【解决方案3】:

    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:检查错误。

    【讨论】:

    • rand.c 是我存储此代码的文件吗?(对不起,我对编译器知之甚少)
    • @jhon 如果你只想要 0 到 2^32 之间的随机数,那么只需从 /dev/random 读取它本身就会给你随机性:P 在你的 shell 中试试这个:od -An -N4 -tu /dev/random | tr -d ' ' 重定向到文件od -An -N4 -tu /dev/random | tr -d ' ' &gt; file.txt 但是是的;如果您将上面的代码复制并粘贴到一个名为 rand.c 的文件中,您实际上可以通过输入上面的命令来编译它。请注意,代码有一个要求,您需要在系统中安装 glib。当然,如果您不使用 Linux,这些都不会起作用。
    • 好的,感谢我能够执行的 shell 命令。但是当我使用上述命令对文件 rand.c 执行此操作时,它会出现符号 >>。
    • 哦,好吧...我希望shell命令能满足您的需要。如果不是,您总是可以提出另一个关于如何编译代码的问题,这很容易。但我真的建议你使用该命令而不是其他人的 C/C++/Java 代码,因为 /dev/random 会产生真正的随机数。
    • 现在可以在 C 中调用上面的脚本我正在使用系统(“/path/myscript.sh”)。它按预期提供输出,但如何在变量中重定向它。例如:int abc=system ("/path/myscirpt.sh")??
    【解决方案4】:

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

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

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

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

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

        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;
            }
        
        }
        

        【讨论】:

          猜你喜欢
          • 2019-05-24
          • 2016-04-04
          • 1970-01-01
          • 1970-01-01
          • 2013-02-27
          • 2015-08-13
          • 2020-08-10
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多