zoukankan      html  css  js  c++  java
  • 笔记 | 如何正确地生成一个随机数

    在最近的一场CF的题解中,提到了这篇blog:Don't use rand(): a guide to random number generators in C++

    大概概述一下这篇神仙blog说了啥:

    • CF评测机上(以及我们会遭遇的许多windows评测机上)RAND_MAX很小,只有32767
    • 不幸的是,random_shuffle用的也是这个自带的rand(),元素在数组里移动的距离也很小。
    • rand()使用的伪随机算法是 linear congruential generator (线性同余发生器),在低位循环节很低。

    那么如何正确地生成一个随机数呢?神仙blog提供了这样一个东西:库里的mt19937。

    这个奇葩的名字来自于它使用的算法——Mersenne Twister算法,以及它用到的质数——(2^{19937} - 1)

    怎么用呢?

    mt19937 rng(seed);
    printf("%u
    ", rng());
    

    上面那句相当于srand(seed),然后调用你定义的rng()可以获得一个unsigned int类型的随机数。

    如果你要生成unsigned long long 类型的话,使用mt19937_64即可。

    那么怎么替代random_shuffle()呢?使用shuffle()函数,把你的mt19937传进去,像这样:

    shuffle(a, a + n, rng);
    

    这样就能让数组内的元素移动足够大的距离——让shuffle更随机了。

    附:完整生成随机数代码

    #include <cstdio>
    #include <chrono>
    #include <random>
    using namespace std;
    
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    
    int main(){
        printf("%u
    ", rng());
        return 0;
    }
    
  • 相关阅读:
    P3444 [POI2006]ORK-Ploughing
    p4555&bzoj2565 最长双回文串
    bzoj2563 阿狸和桃子的游戏
    p4503&bzoj3555 企鹅QQ
    p3627&bzoj1179 抢掠计划(ATM)
    p2279&bzoj1217 消防局的设立
    p2661 信息传递(Tarjan模板)
    p2071 座位安排
    2B The least round way
    JSK 糟糕的bug
  • 原文地址:https://www.cnblogs.com/RabbitHu/p/10390146.html
Copyright © 2011-2022 走看看