C++11--隨機數引擎和隨機數分布


/* 隨機數引擎:
 *    有狀態的隨機數發生器,生成在預定義的最大小值之間的隨機數
 *    不是真正的隨機數--偽隨機
 */
int main ()
{
   std::default_random_engine eng;
	cout << "Min: " << eng.min() << endl; 
	cout << "Max: " << eng.max() << endl;

	cout << eng() << endl;  // 生成一個隨機數
	cout << eng() << endl;  // 生成第二個隨機數

	std::stringstream state;
	state << eng;  // 保存引擎狀態

	cout << eng() << endl;  // 生成一個隨機數
	cout << eng() << endl;  // 生成第二個隨機數

	state >> eng;  // 恢復引擎狀態
	cout << eng() << endl;  // 生成一個隨機數,跟前面的值一模一樣
	cout << eng() << endl;  // 生成第二個隨機數,跟前面的值一模一樣
}


/* 更多例子 */
void printRandom(std::default_random_engine e) {
	for (int i=0; i<10; i++) 
		cout << e() << " ";
	cout << endl;
}


template <typename T>
void printArray(T arr) {
	for (auto v:arr) {
		cout << v << " ";
	}
	cout << endl;
}

int main ()
{
   std::default_random_engine eng;
	printRandom(eng);

	std::default_random_engine eng2;
	printRandom(eng2);    //值跟前面完全一樣,所以引入種子

	unsigned seed = std::chrono::steady_clock::now().time_since_epoch().count();
	std::default_random_engine e3(seed);    //
	printRandom(e3);

	eng.seed();  // 重置引擎為初始狀態
	eng.seed(109); // 依據種子109設置引擎狀態

	eng2.seed(109);
	if (eng == eng2)   // 兩個引擎狀態相同就相同
		cout << "eng and eng2 have the same state" << endl;


	cout << "\n\n Shuffling:" << endl;
	int arr[] = {1,2,3,4,5,6,7,8,9};
	vector<int> d(arr, arr+9);
	printArray(d);

	vector<int> d =  {1,2,3,4,5,6,7,8,9};
	std::shuffle(d.begin(), d.end(), std::default_random_engine());
	printArray(d);
	std::shuffle(d.begin(), d.end(), std::default_random_engine());  // 相同順序
	printArray(d);
	
	std::shuffle(d.begin(), d.end(), eng);
	printArray(d);
	std::shuffle(d.begin(), d.end(), eng);  // 不同順序
	printArray(d);
}

/* 其他隨機數引擎 參看cplusplus.com*/




/* 隨機數分布 */
// 默認的引擎都是均勻分布,且取值范圍固定

int main ()  {
	// 引擎只是提供了一個隨機源
	unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
	std::default_random_engine e(seed);
   // 如何獲取一個0到5之間的隨機數?
   //  e()%6  
	//    -- 隨機性差
	//    -- 只能均勻分布

	std::uniform_int_distribution<int> distr(0,5);  // range: [0,5]  -- 0和5都包含,這個唯一一個全閉區間的特例
													// 默認參數: [0, INT_MAX]
	cout << " int_distribution: " << endl; 
    for (int i=0; i<30; i++) {
        cout << distr(e) << " ";
    }


	cout << "\n\n real_distribution: " << endl;

	std::uniform_real_distribution<double> distrReal(0,5);  // 半開區間: [1, 5) 
														// default param: [0, 1)
    for (int i=0; i<30; i++) {
        cout << distrReal(e) << " ";
    }

	cout << " poisson_distribution: " << endl; 
	std::poisson_distribution<int> distrP(1.0);  //  mean (double) 
    for (int i=0; i<30; i++) {
        cout << distrP(e) << " ";
    }
	cout << endl;	

	cout << " normal_distribution: " << endl; 
	std::normal_distribution<double> distrN(10.0, 3.0);  // 平均值和標准差
	vector<int> v(20);
    for (int i=0; i<800; i++) {
        int num = distrN(e); // convert double to int
		if (num >= 0 && num < 20)
			v[num]++;   // v[num] 記錄數字num出現的次數
    }
	for (int i=0; i<20; i++) {
		cout << i << ": " << std::string(v[i], '*') << endl;
	}
	cout << endl;

	// Stop using rand()%n; 
}

/* 其他分布參看cplusplus.com*/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM