欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c++ 隨機(jī)數(shù)問(wèn)題的相關(guān)研究

 更新時(shí)間:2021年03月08日 09:29:30   作者:啊哈彭  
這篇文章主要介紹了c++ 隨機(jī)數(shù)問(wèn)題的相關(guān)研究,幫助大家更好的理解和學(xué)習(xí)使用c++,感興趣的朋友可以了解下

1、問(wèn)題背景

某項(xiàng)目中有個(gè)復(fù)雜的排序,先是各種規(guī)則依次排序,最后如果依然并列的話(huà),那就隨機(jī)位置,名次并列。測(cè)試中發(fā)現(xiàn)一個(gè)詭異現(xiàn)象,并列時(shí)隨機(jī)排序但隨機(jī)后2個(gè)case打印的順序每次都一樣,隨機(jī)數(shù)沒(méi)有起到任何作用。經(jīng)過(guò)分析發(fā)現(xiàn),隨機(jī)數(shù)種子srand(clock()),本意是希望連續(xù)調(diào)用這個(gè)函數(shù),給多個(gè)隨機(jī)數(shù)設(shè)置種子,實(shí)際上設(shè)置的種子相同,最后產(chǎn)生的隨機(jī)數(shù)是偽隨機(jī)數(shù)。那么有沒(méi)有一種隨機(jī)數(shù)方法可以在較快的循環(huán)中,保證隨機(jī)性呢?

原問(wèn)題較復(fù)雜,給個(gè)類(lèi)似的例子說(shuō)明具體場(chǎng)景:

void test_random()
{
 vector<int> vec;
 vec.resize(100);
 iota(vec.begin(), vec.end(), 1);
 vector<int> vec2(vec);
 
 srand(clock());
 random_shuffle(vec.begin(), vec.end());
 srand(clock());
 random_shuffle(vec2.begin(), vec2.end());
​
 int cnt = 0;
 cout << "vec:" << endl;
 for (auto v : vec) { 
  cout << v << " "; 
  if ((++cnt % 10) == 0) cout << endl;
 }
 cout << endl<< endl;
​
 cnt = 0;
 cout << "vec2:" << endl;
 for (auto v : vec2) {
  cout << v << " ";
  if ((++cnt % 10) == 0) cout << endl;
 }
}

輸出結(jié)果為:

2、rand()和srand()

rand()和srand()是c函數(shù),在stdlib.h中定義,rand()能產(chǎn)生0--32767范圍的隨機(jī)數(shù)。

如果只使用rand,則每次輸出的隨機(jī)數(shù)都是一樣的,相當(dāng)于使用srand(1)作為默認(rèn)種了。如果給定種了,則能產(chǎn)生不同的隨機(jī)數(shù),所以time或clock函數(shù)就是一個(gè)好種子,獲取計(jì)算機(jī)的時(shí)間,用秒或毫秒來(lái)做隨機(jī)數(shù)種子以產(chǎn)生不同的隨機(jī)數(shù)。但是在某些場(chǎng)景下,會(huì)引發(fā)下列問(wèn)題:

問(wèn)題1:在程序運(yùn)行較慢或不需要連續(xù)產(chǎn)生隨機(jī)數(shù)時(shí),用時(shí)鐘當(dāng)做種子沒(méi)有問(wèn)題,但要快速產(chǎn)生不同的組數(shù)的隨機(jī)數(shù)時(shí),就會(huì)出現(xiàn)前面出現(xiàn)的現(xiàn)象,較大概率出現(xiàn)相同的隨機(jī)數(shù)。

問(wèn)題2:如果希望生成某個(gè)范圍的隨機(jī)數(shù),則不好控制,通常會(huì)采用取模的方式,而這種方式會(huì)破壞隨機(jī)數(shù)的分布概率。

// 0--10 的隨機(jī)數(shù)
srand((unsigned int)time(NULL));
int r = rand() % 10
​
// 100--200的隨機(jī)數(shù)
int min = 100;
int max = 200;
srand((unsigned int)time(NULL));
int r = rand() % (max - min) + min
 
// [0--1.0] 浮點(diǎn)數(shù)
srand((unsigned int)time(NULL));
float r = rand() % RAND_MAX

3、c++11 隨機(jī)數(shù)

c++11引入了random頭文件,可以更加精確的產(chǎn)生隨機(jī)數(shù),并且提供了完善的操作接口。C++標(biāo)準(zhǔn)規(guī)定了隨機(jī)數(shù)設(shè)施,包括均勻隨機(jī)位生成器(Uniform random bit generators,URBG)和隨機(jī)數(shù)分布等,定義在<random>中。

參考文檔:http://www.cplusplus.com/reference/random/?kw=random

This library allows to produce random numbers using combinations of generators and distributions:

Generators: Objects that generate uniformly distributed numbers.

Distributions: Objects that transform sequences of numbers generated by a generator into sequences of numbers that follow a specific random variable distribution, such as uniform, Normal or Binomial.

random標(biāo)準(zhǔn)款主要包括:

生成器:生成均勻分布偽隨機(jī)數(shù)的對(duì)象

分布:將生成器生成的數(shù)序列轉(zhuǎn)換為某種特定數(shù)學(xué)概率分布的序列,如均勻分布、正態(tài)分布、泊松分布等。

3.1、生成器

1)random_device生成器

C++11提供了一個(gè)random_device隨機(jī)數(shù)類(lèi),英文叫“Non-deterministic random number generator”,這是一個(gè)非確定性隨機(jī)數(shù)生成器,它并不是由某一個(gè)數(shù)學(xué)算法得到的隨機(jī)序列,而是通過(guò)讀取文件,讀什么文件看具體的實(shí)現(xiàn)(Linux可以通過(guò)讀取/dev/random文件來(lái)獲取)。文件的內(nèi)容是隨機(jī)的,簡(jiǎn)單理解即這個(gè)類(lèi)依靠系統(tǒng)的噪聲產(chǎn)生隨機(jī)數(shù)。

2)偽隨機(jī)數(shù)引擎

偽隨機(jī)數(shù)引擎,實(shí)現(xiàn)方式屬于模板類(lèi),是使用算法根據(jù)初始種子生成偽隨機(jī)數(shù)的生成器。

linear_congruential_engine:線(xiàn)性同余生成引擎,是最常用也是速度最快的,但隨機(jī)效果一般
mersenne_twister_engine:梅森旋轉(zhuǎn)算法,隨機(jī)效果最好。
subtract_with_carry_engine:滯后Fibonacci算法。

隨機(jī)數(shù)引擎需要一個(gè) 整型參數(shù)作為種子,對(duì)于給定的單個(gè)或多個(gè)種子,隨機(jī)數(shù)生成器總會(huì)生成相同的序列,這在測(cè)試時(shí)非常有用。當(dāng)測(cè)試完成,則需要隨機(jī)的種子以產(chǎn)出不同的隨機(jī)數(shù),推薦使用random_device作為隨機(jī)數(shù)種子。

3.2、適配器

除了生成器模板庫(kù)外,c++11還設(shè)計(jì)了幾種適配器。

discard_block_engine: Discard-block random number engine adaptor (class template ) independent_bits_engine: Independent-bits random number engine adaptor (class template ) shuffle_order_engine :Shuffle-order random number engine adaptor (class template )

3.3、隨機(jī)分布模板類(lèi)

隨機(jī)數(shù)引擎產(chǎn)生的隨機(jī)數(shù)值都比較大,使用時(shí)經(jīng)常需要限定到一個(gè)范圍內(nèi),c++11提供了符合各種概率分布的隨機(jī)數(shù)生成模板類(lèi),比如:均勻分布,正態(tài)分布,泊松分布等。

以均勻分布為例:

template< class IntType = int > class uniform_int_distribution;
template< class RealType = double > class uniform_real_distribution;

測(cè)試1:直接使用引擎產(chǎn)生隨機(jī)數(shù),范圍很大。

random_device rd;
mt19937 g(rd());
for (int n = 0; n < 10; ++n)
{
 cout << g() << " ";
}
/* 輸出
case 1: 
649838310 2697128147 116396177 1728659882 2608399735 1196122003 1824385544 3670102805 2610106284 1577110367
case 2:
2220490604 2877041131 4118289859 1423499548 3901014967 230558428 3106974485 2887363336 1389836600 4020707730
*/

測(cè)試2:使用均勻分布類(lèi)模板產(chǎn)生隨機(jī)數(shù),可以限定生成的隨機(jī)數(shù)的范圍。

random_device rd;
mt19937 g(rd());
uniform_int_distribution<> dis(1, 100);
for (int n = 0; n < 10; ++n)
{
 cout << dis(g) << " ";
}
/* 輸出
case 1: 67 23 61 3 91 88 81 61 57 60
case 2: 51 1 29 75 81 32 8 8 47 5
cae 3: 92 1 22 24 84 20 72 27 66 39
*/

3.4、用法總結(jié)

1、定義種子,可以是隨機(jī)種子或者固定種子,固定種子方便測(cè)試用,但每次產(chǎn)生的隨機(jī)數(shù)都一致。

2、選擇隨機(jī)引擎,把種子值傳入當(dāng)做參數(shù)。

3、選擇合適分布方式,創(chuàng)建隨機(jī)分布對(duì)象,可以在此時(shí)指定需要的隨機(jī)數(shù)的范圍。

4、把引擎?zhèn)魅腚S機(jī)數(shù)分布模板類(lèi)對(duì)象,輸出隨機(jī)數(shù)。

4、問(wèn)題解決

c++ 提供了一個(gè)shuffle函數(shù),相比于random_shuffle,shuffle可以指定隨機(jī)數(shù)引擎,如果指定一個(gè)非確定性引擎,則能保證連續(xù)生成的兩組隨機(jī)數(shù)各不相同,達(dá)到設(shè)計(jì)效果。

template <class _RanIt, class _Urng>
void shuffle(_RanIt _First, _RanIt _Last, _Urng&& _Func)

修改后的測(cè)試函數(shù):

void test_random()
{
 vector<int> vec;
 vec.resize(100);
 iota(vec.begin(), vec.end(), 1);
 vector<int> vec2(vec);
 
 auto engine = std::default_random_engine(std::random_device()());
 shuffle(vec.begin(), vec.end(), engine);
 shuffle(vec2.begin(), vec2.end(), engine);
  
​
 int cnt = 0;
 cout << "vec:" << endl;
 for (auto v : vec) { 
  cout << v << " "; 
  if ((++cnt % 10) == 0) cout << endl;
 }
 cout << endl<< endl;
​
 cnt = 0;
 cout << "vec2:" << endl;
 for (auto v : vec2) {
  cout << v << " ";
  if ((++cnt % 10) == 0) cout << endl;
 }
}

上面例子using default_random_engine = mt19937; 其中,mt19937是一個(gè)引擎,最大值為0Xffffffff。

using mt19937 = mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 0x9908b0df, 11, 0xffffffff, 7, 0x9d2c5680, 15,  0xefc60000, 18, 1812433253>;

輸出結(jié)果為:

vec:
85 7 58 8 29 17 60 57 81 71
82 93 4 47 84 40 65 79 37 24
3 14 36 25 32 16 91 48 86 38
63 78 80 28 44 39 34 90 69 13
74 1 77 59 88 41 46 56 33 62
21 18 30 52 89 22 87 27 9 53
70 51 2 72 92 42 26 66 73 97
15 43 31 49 100 68 54 35 12 99
6 67 5 96 94 83 10 45 61 50
23 76 19 98 11 55 75 20 95 64

vec2:
37 51 12 62 99 95 65 1 78 29
80 13 48 72 83 23 25 75 97 68
86 40 24 30 84 4 47 28 76 57
33 38 16 18 69 9 70 31 42 49
52 71 91 96 81 73 34 45 10 26
2 93 89 41 54 64 44 22 36 39
87 43 63 55 3 32 27 19 85 79
35 5 58 11 56 59 21 88 15 100
74 53 8 14 60 92 17 50 7 90
6 20 67 77 98 61 66 82 46 94

c++隨機(jī)數(shù)問(wèn)題研究

原創(chuàng)首發(fā):https://www.cnblogs.com/pingwen/p/14496607.html

以上就是c++ 隨機(jī)數(shù)問(wèn)題的相關(guān)研究的詳細(xì)內(nèi)容,更多關(guān)于c++隨機(jī)數(shù)問(wèn)題研究的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • VC實(shí)現(xiàn)五子棋游戲的一個(gè)算法示例

    VC實(shí)現(xiàn)五子棋游戲的一個(gè)算法示例

    這篇文章主要介紹了VC實(shí)現(xiàn)五子棋游戲的一個(gè)算法示例,對(duì)于學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法的朋友有一定的借鑒價(jià)值,需要的朋友可以參考下
    2014-08-08
  • C++中友元函數(shù)(friend)解析

    C++中友元函數(shù)(friend)解析

    這篇文章主要分享了C++友元函數(shù)講解,C++提供了一種形式的訪(fǎng)問(wèn)權(quán)限,叫做友元,友元有三種,分別是友元函數(shù)、友元類(lèi)和友元成員函數(shù),下面將詳細(xì)介紹該內(nèi)容,需要的小伙伴可以參考一下
    2022-01-01
  • Qt項(xiàng)目打包的實(shí)現(xiàn)步驟

    Qt項(xiàng)目打包的實(shí)現(xiàn)步驟

    本文主要介紹了Qt項(xiàng)目打包的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • C語(yǔ)言實(shí)現(xiàn)進(jìn)程間通信原理解析

    C語(yǔ)言實(shí)現(xiàn)進(jìn)程間通信原理解析

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)進(jìn)程間通信原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • C++實(shí)現(xiàn)通訊錄管理系統(tǒng)項(xiàng)目

    C++實(shí)現(xiàn)通訊錄管理系統(tǒng)項(xiàng)目

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)通訊錄管理系統(tǒng)項(xiàng)目,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 一起來(lái)看看C語(yǔ)言的預(yù)處理注意點(diǎn)

    一起來(lái)看看C語(yǔ)言的預(yù)處理注意點(diǎn)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言的預(yù)處理,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • C語(yǔ)言中main函數(shù)兩個(gè)參數(shù)的作用

    C語(yǔ)言中main函數(shù)兩個(gè)參數(shù)的作用

    這篇文章主要介紹了C語(yǔ)言中main函數(shù)兩個(gè)參數(shù)的作用,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09
  • VS2017+Qt5+Opencv3.4調(diào)用攝像頭拍照并存儲(chǔ)

    VS2017+Qt5+Opencv3.4調(diào)用攝像頭拍照并存儲(chǔ)

    本文主要介紹了VS2017+Qt5+Opencv3.4調(diào)用攝像頭拍照并存儲(chǔ),實(shí)現(xiàn)了視頻,拍照,保存這三個(gè)功能。具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • C++實(shí)現(xiàn)合并兩個(gè)排序的鏈表

    C++實(shí)現(xiàn)合并兩個(gè)排序的鏈表

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)合并兩個(gè)排序的鏈表,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-03-03
  • 一篇文章教你在C++中操作符可分為哪幾種類(lèi)和用法

    一篇文章教你在C++中操作符可分為哪幾種類(lèi)和用法

    這篇文章主要介紹了C++編程中操作符的種類(lèi)和用法,是C++入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下,希望能夠給你帶來(lái)幫助
    2021-09-09

最新評(píng)論