Skip to content

随机数的用法

前言

c++里有两种随机数生成的方式

随机数据生成

标准库<cstdlib>(被包含于<iostream>中)提供两个帮助生成伪随机数的函数: rand,srand.

1.rand函数:

int rand(void):返回一随机数值的范围在0至RAND_MAX 间

rand()产生的是伪随机数字,每次执行时是相同的;若要不同,用函数srand()初始化它。

2.srand函数: 随机种子初始化函数

void srand(unsigned int seed):如果每次seed都设相同值,rand()所产生的随机数值每次就会一样。

3.使用当前时钟作为随机数种子:

头文件:#include <ctime>

定义函数:time_t time(time_t *t);

函数说明:此函数会返回从公元 1970 年1 月1 日的UTC 时间从0 时0 分0 秒算起到现在所经过的秒数。如果t 并非空指针的话,此函数也会将返回值存到t 指针所指的内存

!!!注:RAND_MAX取值不同会带来不同的效果,有可能会产生陷阱,具体看这个链接:揭秘rand()函数

利用srand((unsigned int)time(NULL))的方法,产生不同的随机数种子,因为每一次运行程序的时间是不同的。

简易的样例代码:0~RAND_MAX之间的随机数程序

#include <ctime>
#include <cstdio>
#include <cstdlib> //使用srand

int main(){
    srand((unsigned int)time(NULL));
    int i;
    for(i = 0;i<10;i++){
        printf("rand num %d: %d \n",i,rand());
    }
    int k = RAND_MAX;
	printf("RAND_MAX = %d %x\n",k,k); // MinGW下的RAND_MAX值:7fff,32767
	//linux GCC 下 RAND_MAX 应该是:7fffffff,2147483647
	//http://en.cppreference.com/w/cpp/numeric/random/RAND_MAX
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

**5.产生一定范围随机数的通用表示公式 **

  • 要取得[a,b)的随机整数,使用(rand() % (b-a))+ a;
  • 要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a;
  • 要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1;
  • 通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。
  • 要取得a到b之间的随机整数,另一种表示:a + (int)b * rand() / (RAND_MAX + 1)。
  • 要取得0~1之间的浮点数,可以使用rand() / double(RAND_MAX)。

6.模板

c
#include <cstdio>
#include <cstdlib>
#include <ctime>


/* [a,b]之间的随机数 */
int getRand(int a,int b){
    return (rand()%(b-a+1)+a);
}
int main(){
    //srand( (unsigned int)time(NULL));
    int seed;scanf("%d",&seed);//自己读取种子
    srand((unsigned int)seed);

    printf("%d",getRand(1,10));

    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

C++11随机数发生器的使用

http://zh.cppreference.com/w/cpp/header/random

linux下sleep函数的使用

#include <unistd.h>
#include <cstdio>

int main(){
    printf("befero sleep 1 second\n");
    sleep(1);
    printf("after sleep 1 second\n");
    return 0;
}
1
2
3
4
5
6
7
8
9

c++ 风格random使用

简单使用

cpp
#include <random>
#include <iostream>
 
int main()
{
    std::random_device rd;  //Will be used to obtain a seed for the random number engine
    std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
    std::uniform_int_distribution<> distrib(1, 6);
 
    for (int n=0; n<10; ++n)
        //Use `distrib` to transform the random unsigned int generated by gen into an int in [1, 6]
        std::cout << distrib(gen) << ' ';
    std::cout << '\n';
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

封装起来用

cpp
struct Random {
    std::random_device rd;
    mt19937 engine{rd()};
    uniform_int_distribution<long long> dis; // in [0,0x7fffffffffffffff]
    Random(){}
    Random(int l,int r){ dis = uniform_int_distribution<long long> (l,r); }

    int operator()(){ return dis(engine); }
    template<typename U> //产生一定范围内的随机数
    U operator()(U l,U r){ return dis(engine) % ( r-l+1 ) + l; }

    Random create(int l,int r){ return Random(l,r); } //工厂模式
} rnd;

1
2
3
4
5
6
7
8
9
10
11
12
13
14

结合两者的优点

  • c风格的随机数只有一秒内执行一次
  • c++风格要记的代码太多
cpp
#include <iostream>
#include <random>
#include <ctime>
#include <cstdlib>

struct random {
    random() {
        srand(std::random_device()());
    }
    int operator()(int l,int r){
        return rand() % (r-l+1) +l;
    }
    int operator()(){ return rand();}
} _rnd;

int main(){
    for(int i=1;i<=10;++i){
        std::cout << _rnd(5,10) << " ";
    }
    std::cout << "\n";
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

参考