日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

线性同余法产生随机数C语言,使用线性同余法生成伪随机数/序列(C++实现)

發布時間:2024/8/1 c/c++ 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 线性同余法产生随机数C语言,使用线性同余法生成伪随机数/序列(C++实现) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近朋友提出一個問題,自己編寫函數生成隨機數,一開始沒有認真思考,后來想了一下,如果是學習過計算機密碼學,應該很快就能設計出一些算法,這里使用了數論領域的相關知識——線性同余法簡單實現了生成隨機數算法。

以下是網上關于隨機數生成的一類說法:

在計算機上可以用物理方法來產生隨機數,但價格昂貴,不能重復,使用不便。另一種方法是用數學遞推公式產生,這樣產生的序列與真正的隨機數序列不同,所以稱為偽隨機數或偽隨機序列,只要方法和參數選擇合適,所產生的偽隨機數就能滿足均勻性和獨立性,與真正的隨機數具有相近的性質。

以下是一個使用了線性同余的遞推公式:

Xt = (X0 * 17 + 29) mod 500

線性同余中的線性,是指“線性”表示方程中 x 的次數是一次,mod 取余運算符則體現了“同余”這一數學概念。

式中,17 、29和500分別稱做乘數、增量和模數。使用線性同余生成隨機數的方法速度快,但對乘數、增量和模數的選取有一定的要求:

多次使用線性同余公式產生的序列應該看起來是隨機的,不循環的;

乘數/增量與模數互質;

這個函數能夠產生一個完整周期內的所有隨機數。這一要求由模數控制。

#include

#include

class MyRand

{

public:

unsigned int seed;

// 默認使用系統時間為種子

// time(NULL) 返回從1970年元旦午夜0點到現在的秒數

void srand(unsigned int s = (unsigned int)time(NULL))

{

seed = s;

}

// 使用了一種線性同余法,得到的隨機數最大為(2^15-1),29為質數中的一個

unsigned int rand()

{

seed = (seed * 31 + 13) % ((1 << 15) - 1);

return seed;

}

};

#include "rand.h"

int main()

{

MyRand a;

a.srand(); // 使用系統時間為種子

std::cout << "產生若干個隨機數:" << std::endl;

for (int i = 0; i < 100; i++)

std::cout << a.rand() % 100 << " "; // 生成0~100之間的隨機數

getchar();

return 0;

}

使用錯誤的公式,得到的序列并不隨機:

得到符合要求的偽隨機數序列:

在生成隨機數的過程中,會強調生成的是“偽”隨機數,這是因為平時編程中調用rand()函數(包括以上設計的函數)所產生的隨機數都是按照一定的公式模擬產生的,其結果是確定而可預見的。慶幸的是,若給rand()函數(包括以上自己設計的函數)提供不同的初始值(成為隨機種子seed),以真隨機數為運算的初始條件,就可以得到真正意義上的隨機數。

就牽扯到產生隨機種子的方法。產生種子的方法有很多,在程序設計的課程中介紹得最多的是使用系統時間time為種子。代碼中使用了time(NULL) 返回從1970年元旦午夜0點到現在的秒數作為隨機序列運算的初始值,每一次調用rand(),可得到不同的隨機序列。

事實上這種產生隨機種子的方法有一定的缺陷性。假設在一臺計算機上運行批量執行程序,程序執行的時間是幾個ms,那么幾個相鄰程序的seed是一樣的,每次調用隨機數生成函數的結果也是一樣的。這是因為系統時間time是按照秒級來計算的,而程序執行的時間是毫秒級,倘若在一秒內執行多次程序,必然導致產生的隨機種子相同。

總結

以上是生活随笔為你收集整理的线性同余法产生随机数C语言,使用线性同余法生成伪随机数/序列(C++实现)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。