當前位置:首頁 » 操作系統 » 偽隨機演算法

偽隨機演算法

發布時間: 2022-02-06 01:57:09

A. 偽隨機數的生成方法

一般地,偽隨機數的生成方法主要有以下3種:
(1) 直接法(Direct Method),根據分布函數的物理意義生成。缺點是僅適用於某些具有特殊分布的隨機數,如二項式分布、泊松分布。
(2) 逆轉法(Inversion Method),假設U服從[0,1]區間上的均勻分布,令X=F-1(U),則X的累計分布函數(CDF)為F。該方法原理簡單、編程方便、適用性廣。
(3)接受拒絕法(Acceptance-Rejection Method):假設希望生成的隨機數的概率密度函數(PDF)為f,則首先找到一個PDF為g的隨機數發生器與常數c,使得f(x)≤cg(x),然後根據接收拒絕演算法求解。由於演算法平均運算c次才能得到一個希望生成的隨機數,因此c的取值必須盡可能小。顯然,該演算法的缺點是較難確定g與c。
因此,偽隨機數生成器(PRNG)一般採用逆轉法,其基礎是均勻分布,均勻分布PRNG的優劣決定了整個隨機數體系的優劣[7]。下文研究均勻分布的PRNG。

B. 偽隨機數怎麼找規律

真正意義上的隨機數(或者隨機事件)在某次產生過程中是按照實驗過程中表現的分布概率隨機產生的,其結果是不可預測的,是不可見的。而計算機中的隨機函數是按照一定演算法模擬產生的,其結果是確定的,是可見的。我們可以這樣認為這個可預見的結果其出現的概率是100%。所以用計算機隨機函數所產生的「隨機數」並不隨機,是偽隨機數。

一般地,偽隨機數的生成方法主要有以下3種:

(1) 直接法(Direct Method),根據分布函數的物理意義生成。缺點是僅適用於某些具有特殊分布的隨機數,如二項式分布、泊松分布。

(2) 逆轉法(Inversion Method),假設U服從[0,1]區間上的均勻分布,令X=F-1(U),則X的累計分布函數(CDF)為F。該方法原理簡單、編程方便、適用性廣。

(3)接受拒絕法(Acceptance-Rejection Method):假設希望生成的隨機數的概率密度函數(PDF)為f,則首先找到一個PDF為g的隨機數發生器與常數c,使得f(x)≤cg(x),然後根據接收拒絕演算法求解。由於演算法平均運算c次才能得到一個希望生成的隨機數,因此c的取值必須盡可能小。顯然,該演算法的缺點是較難確定g與c。

因此,偽隨機數生成器(PRNG)一般採用逆轉法,其基礎是均勻分布,均勻分布PRNG的優劣決定了整個隨機數體系的優劣。下文研究均勻分布的PRNG。

偽隨機數發生器

C. 演算法的偽隨機性 定義

偽隨機性過程指短期內可以預測的確定性系統,長期運行下去反而變的不可預測。對於偽隨機性過程,只要數據准確,下一次的結果是可以預先確定的。只是由於不斷迭代的結果,長期下去以至差之毫釐,失之千里,系統才變的神秘莫測。

D. 隨機數和偽隨機數的計算公式都是什麼呀

為追求真正的隨機序列,人們曾採用很多種原始的物理方法用於生成一定范圍內滿足精度(位數)的均勻分布序列,其缺點在於:速度慢、效率低、需佔用大量存儲空間且不可重現等。為滿足計算機模擬研究的需求,人們轉而研究用演算法生成模擬各種概率分布的偽隨機序列。偽隨機數是指用數學遞推公式所產生的隨機數。從實用的角度看,獲取這種數的最簡單和最自然的方法是利用計算機語言的函數庫提供的隨機數發生器。典型情況下,它會輸出一個均勻分布在0和1區間內的偽隨機變數的值。其中應用的最為廣泛、研究最徹底的一個演算法即線性同餘法。

線性同餘法LCG(Linear Congruence Generator)

選取足夠大的正整數M和任意自然數n0,a,b,由遞推公式:

ni+1=(af(ni)+b)mod M i=0,1,…,M-1

生成的數值序列稱為是同餘序列。當函數f(n)為線性函數時,即得到線性同餘序列:

ni+1=(a*ni+b)mod M i=0,1,…,M-1

以下是線性同餘法生成偽隨機數的偽代碼:

Random(n,m,seed,a,b)
{
r0 = seed;
for (i = 1;i<=n;i++)
ri = (a*ri-1 + b) mod m
}

其中種子參數seed可以任意選擇,常常將它設為計算機當前的日期或者時間;m是一個較大數,可以把它取為2w,w是計算機的字長;a可以是0.01w和0.99w之間的任何整數。

應用遞推公式產生均勻分布隨機數時,式中參數n0,a,b,M的選取十分重要。

例如,選取M=10,a=b =n0=7,生成的隨機序列為{6,9,0,7,6,9,……},周期為4。

取M=16,a=5,b =3,n0=7,生成的隨機序列為{6,1,8,11,10,5,12,15,14,9,0,3,2,13,4,7,6,1……},周期為16。

取M=8,a=5,b =1,n0=1,生成的隨機序列為{6,7,4,5,2,3,0,1,6,7……},周期為8。

Visual C++中偽隨機數生成機制

用VC產生隨機數有兩個函數,分別為rand(void)和srand(seed)。rand()產生的隨機整數是在0~RAND_MAX之間平均分布的,RAND_MAX是一個常量(定義為:#define RAND_MAX 0x7fff)。它是short型數據的最大值,如果要產生一個浮點型的隨機數,可以將rand()/1000.0,這樣就得到一個0~32.767之間平均分布的隨機浮點數。如果要使得范圍大一點,那麼可以通過產生幾個隨機數的線性組合來實現任意范圍內的平均分布的隨機數。

其用法是先調用srand函數,如

srand( (unsigned)time( NULL ) )

這樣可以使得每次產生的隨機數序列不同。如果計算偽隨機序列的初始數值(稱為種子)相同,則計算出來的偽隨機序列就是完全相同的。要解決這個問題,需要在每次產生隨機序列前,先指定不同的種子,這樣計算出來的隨機序列就不會完全相同了。以time函數值(即當前時間)作為種子數,因為兩次調用rand函數的時間通常是不同的,這樣就可以保證隨機性了。也可以使用srand函數來人為指定種子數分析以下兩個程序段,

程序段1:

//包含頭文件
void main() {
int count=0;
for (int i=0;i<10;i++){
srand((unsigned)time(NULL));
count++;
cout<<"No"<
//包含頭文件
void main() {
int count=0;
srand((unsigned)time(NULL));
for (int i=0;i<10;i++){
count++;
cout<<"No"<
No1=9694 No2=9694 No3=9694 No4=9694 No5=9694
No6=9694 No7=9694 No8=9694 No9=9694 No10=9694

程序段2的運行結果為:

No1=10351 No2=444 No3=11351 No4=3074 No5=21497
No6=30426 No7=6246 No8=24614 No9=22089 No10=21498

可以發現,以上兩個程序段由於隨機數生成時選擇的種子的不同,運行的結果也不一樣。rand()函數返回隨機數序列中的下一個數(實際上是一個偽隨機數序列,序列中的每一個數是由對其前面的數字進行復雜變換得到的)。為了模模擬正的隨機性,首先要調用srand()函數給序列設置一個種子。為了更好地滿足隨機性,使用了時間函數time(),以便取到一個隨時間變化的值,使每次運行rand()函數時從srand()函數所得到的種子值不相同。偽隨機數生成器將作為"種子"的數當作初始整數傳給函數。這粒種子會使這個球(生成偽隨機數)一直滾下去。

程序段1中由於將srand()函數放在循環體內,而程序執行的CPU時間較快,調用time函數獲取的時間精度卻較低(55ms),這樣循環體內每次產生隨機數用到的種子數都是一樣的,因此產生的隨機數也是一樣的。而程序段2中第1次產生的隨機數要用到隨機種子,以後的每次產生隨機數都是利用遞推關系得到的。 基於MFC的隨機校驗碼生成

Web應用程序中經常要利用到隨機校驗碼,校驗碼的主要作用是防止黑客利用工具軟體在線破譯用戶登錄密碼,校驗碼、用戶名、密碼三者配合組成了進入Web應用系統的鑰匙。在利用VC開發的基於客戶機/瀏覽器(Client/Server)模式的應用軟體系統中,為了防止非法用戶入侵系統,通常也要運用隨機校驗碼生成技術。

E. 偽隨機數演算法(basic進,不要c語言

知道的不多,呵呵~~~~~~~~~
所謂偽隨機數,就是說vb中所謂的隨機數函數(Rnd)並不是真正(完全)的隨機數,它還是受到某些條件約束的。舉個例子吧,新建一個工程,然後在form_load事件中加入Msgbox
Rnd,不加其它任何語句,你會發現程序每次運行時彈出的數據都相同。
所以,若要生成較好的隨機數,一般會在使用Rnd之前先使用randomize或randomize
timer。

F. 什麼是偽隨機數與真隨機數

首先需要聲明的是,計算機不會產生絕對隨機的隨機數,計算機只能產生「偽隨機數」。其實絕對隨機的隨機數只是一種理想的隨機數,即使計算機怎樣發展,它也不會產生一串絕對隨機的隨機數。計算機只能生成相對的隨機數,即偽隨機數。

偽隨機數並不是假隨機數,這里的「偽」是有規律的意思,就是計算機產生的偽隨機數既是隨機的又是有規律的。怎樣理解呢?產生的偽隨機數有時遵守一定的規律,有時不遵守任何規律;偽隨機數有一部分遵守一定的規律;另一部分不遵守任何規律。比如「世上沒有兩片形狀完全相同的樹葉」,這正是點到了事物的特性,即隨機性,但是每種樹的葉子都有近似的形狀,這正是事物的共性,即規律性。從這個角度講,你大概就會接受這樣的事實了:計算機只能產生偽隨機數而不能產生絕對隨機的隨機數。

那麼計算機中隨機數是怎樣產生的呢?有人可能會說,隨機數是由「隨機種子」產生的。沒錯,隨機種子是用來產生隨機數的一個數,在計算機中,這樣的一個「隨機種子」是一個無符號整形數。那麼隨機種子是從哪裡獲得的呢?

下面看這樣一個C程序:

//rand01.c
#include<dos.h>

static unsigned int RAND_SEED;

unsigned int random(void)
{
RAND_SEED=(RAND_SEED*123+59)%65536;
return(RAND_SEED);
}

void random_start(void)
{
int temp[2];
movedata(0x0040,0x006c,FP_SEG(temp),FP_OFF(temp),4);
RAND_SEED=temp[0];
}

main()
{
unsigned int i,n;
random_start();
for(i=0;i<10;i++)
printf("%u\t",random());
printf("\n");
}

這個程序(rand01.c)完整地闡述了隨機數產生的過程:
首先,主程序調用random_start()方法,random_start()方法中的這一句我很感興趣:

movedata(0x0040,0x006c,FP_SEG(temp),FP_OFF(temp),4);

這個函數用來移動內存數據,其中FP_SEG(far pointer to segment)是取temp數組段地址的函數,FP_OFF(far pointer to offset)是取temp數組相對地址的函數,movedata函數的作用是把位於0040:006CH存儲單元中的雙字放到數組temp的聲明的兩個存儲單元中。這樣可以通過temp數組把0040:006CH處的一個16位的數送給RAND_SEED。

random用來根據隨機種子RAND_SEED的值計算得出隨機數,其中這一句:

RAND_SEED=(RAND_SEED*123+59)%65536;

是用來計算隨機數的方法,隨機數的計算方法在不同的計算機中是不同的,即使在相同的計算機中安裝的不同的操作系統中也是不同的。我在linux和windows下分別試過,相同的隨機種子在這兩種操作系統中生成的隨機數是不同的,這說明它們的計算方法不同。

現在,我們明白隨機種子是從哪兒獲得的,而且知道隨機數是怎樣通過隨機種子計算出來的了。那麼,隨機種子為什麼要在內存的0040:006CH處取?0040:006CH處存放的是什麼?

學過《計算機組成原理與介面技術》這門課的人可能會記得在編制ROM BIOS時鍾中斷服務程序時會用到Intel 8253定時/計數器,它與Intel 8259中斷晶元的通信使得中斷服務程序得以運轉,主板每秒產生的18.2次中斷正是處理器根據定時/記數器值控制中斷晶元產生的。在我們計算機的主機板上都會有這樣一個定時/記數器用來計算當前系統時間,每過一個時鍾信號周期都會使記數器加一,而這個記數器的值存放在哪兒呢?沒錯,就在內存的0040:006CH處,其實這一段內存空間是這樣定義的:

TIMER_LOW DW ? ;地址為 0040:006CH
TIMER_HIGH DW ? ;地址為 0040:006EH
TIMER_OFT DB ? ;地址為 0040:0070H

時鍾中斷服務程序中,每當TIMER_LOW轉滿時,此時,記數器也會轉滿,記數器的值歸零,即TIMER_LOW處的16位二進制歸零,而TIMER_HIGH加一。rand01.c中的

movedata(0x0040,0x006c,FP_SEG(temp),FP_OFF(temp),4);

正是把TIMER_LOW和TIMER_HIGH兩個16位二進制數放進temp數組,再送往RAND_SEED,從而獲得了「隨機種子」。

現在,可以確定的一點是,隨機種子來自系統時鍾,確切地說,是來自計算機主板上的定時/計數器在內存中的記數值。這樣,我們總結一下前面的分析,並討論一下這些結論在程序中的應用:

1.隨機數是由隨機種子根據一定的計算方法計算出來的數值。所以,只要計算方法一定,隨機種子一定,那麼產生的隨機數就不會變。

看下面這個C++程序:

//rand02.cpp
#include <iostream>
#include <ctime>
using namespace std;

int main()
{
unsigned int seed=5;
srand(seed);
unsigned int r=rand();
cout<<r<<endl;
}

在相同的平台環境下,編譯生成exe後,每次運行它,顯示的隨機數都是一樣的。這是因為在相同的編譯平台環境下,由隨機種子生成隨機數的計算方法都是一樣的,再加上隨機種子一樣,所以產生的隨機數就是一樣的。

2.只要用戶或第三方不設置隨機種子,那麼在默認情況下隨機種子來自系統時鍾(即定時/計數器的值)

看下面這個C++程序:

//rand03.cpp
#include <iostream>
#include <ctime>
using namespace std;

int main()
{
srand((unsigned)time(NULL));
unsigned int r=rand();
cout<<r<<endl;
return 0;
}

這里用戶和其他程序沒有設定隨機種子,則使用系統定時/計數器的值做為隨機種子,所以,在相同的平台環境下,編譯生成exe後,每次運行它,顯示的隨機數會是偽隨機數,即每次運行顯示的結果會有不同。

3.建議:如果想在一個程序中生成隨機數序列,需要至多在生成隨機數之前設置一次隨機種子。

看下面這個用來生成一個隨機字元串的C++程序:

//rand04.cpp
#include<iostream>
#include<time.h>
using namespace std;
int main()
{
int rNum,m=20;
char *ch=new char[m];

for ( int i = 0; i<m; i++ ){
//大家看到了,隨機種子會隨著for循環在程序中設置多次
srand((unsigned)time(NULL));
rNum=1+(int)((rand()/(double)RAND_MAX)*36); //求隨機值
switch (rNum){
case 1: ch[i]='a';
break ;
case 2: ch[i]='b';
break ;
case 3: ch[i]='c';
break ;
case 4: ch[i]='d';
break ;
case 5: ch[i]='e';
break ;
case 6: ch[i]='f';
break ;
case 7: ch[i]='g';
break ;
case 8: ch[i]='h';
break ;
case 9: ch[i]='i';
break ;
case 10: ch[i]='j';
break ;
case 11: ch[i]='k';
break ;
case 12: ch[i]='l';
break ;
case 13: ch[i]='m';
break ;
case 14: ch[i]='n';
break ;
case 15: ch[i]='o';
break ;
case 16: ch[i]='p';
break ;
case 17: ch[i]='q';
break ;
case 18: ch[i]='r';
break ;
case 19: ch[i]='s';
break ;
case 20: ch[i]='t';
break ;
case 21: ch[i]='u';
break ;
case 22: ch[i]='v';
break ;
case 23: ch[i]='w';
break ;
case 24: ch[i]='x';
break ;
case 25: ch[i]='y';
break ;
case 26: ch[i]='z';
break ;
case 27:ch[i]='0';
break;
case 28:ch[i]='1';
break;
case 29:ch[i]='2';
break;
case 30:ch[i]='3';
break;
case 31:ch[i]='4';
break;
case 32:ch[i]='5';
break;
case 33:ch[i]='6';
break;
case 34:ch[i]='7';
break;
case 35:ch[i]='8';
break;
case 36:ch[i]='9';
break;
}//end of switch
cout<<ch[i];
}//end of for loop

cout<<endl;
return 0;
}

而運行結果顯示的隨機字元串的每一個字元都是一樣的,也就是說生成的字元序列不隨機,所以我們需要把srand((unsigned)time(NULL)); 從for循環中移出放在for語句前面,這樣可以生成隨機的字元序列,而且每次運行生成的字元序列會不同(呵呵,也有可能相同,不過出現這種情況的幾率太小了)。
如果你把srand((unsigned)time(NULL));改成srand(2);這樣雖然在一次運行中產生的字元序列是隨機的,但是每次運行時產生的隨機字元序列串是相同的。把srand這一句從程序中去掉也是這樣。

此外,你可能會遇到這種情況,在使用timer控制項編製程序的時候會發現用相同的時間間隔生成的一組隨機數會顯得有規律,而由用戶按鍵command事件產生的一組隨機數卻顯得比較隨機,為什麼?根據我們上面的分析,你可以很快想出答案。這是因為timer是由計算機時鍾記數器精確控制時間間隔的控制項,時間間隔相同,記數器前後的值之差相同,這樣時鍾取值就是呈線性規律的,所以隨機種子是呈線性規律的,生成的隨機數也是有規律的。而用戶按鍵事件產生隨機數確實更呈現隨機性,因為事件是由人按鍵引起的,而人不能保證嚴格的按鍵時間間隔,即使嚴格地去做,也不可能完全精確做到,只要時間間隔相差一微秒,記數器前後的值之差就不相同了,隨機種子的變化就失去了線性規律,那麼生成的隨機數就更沒有規律了,所以這樣生成的一組隨機數更隨機。這讓我想到了各種晚會的抽獎程序,如果用人來按鍵產生幸運觀眾的話,那就會很好的實現隨機性原則,結果就會更公正。

最後,我總結兩個要點:
1.計算機的偽隨機數是由隨機種子根據一定的計算方法計算出來的數值。所以,只要計算方法一定,隨機種子一定,那麼產生的隨機數就是固定的。
2.只要用戶或第三方不設置隨機種子,那麼在默認情況下隨機種子來自系統時鍾。

G. 誰可以告訴我偽隨機函數是什麼

隨機數,就是無規律出現的數字。由於真正的隨機數存在不存在還是個迷,因此也就產生了偽隨機數。而偽隨機數是人們為了模擬隨機數產生而設計演算法去實現得到的一組數字。因為是由人們設計的,因此偽隨機數是有一定規律的,並不是真正的隨機數。
偽隨機數是由隨機種子和演算法兩個方面決定的。比如說,用一列很長的數組去產生偽隨機數,種子決定從哪兒開始取數,而演算法決定怎麼取,在什麼范圍內取。........4,1,2,6,7,9,435,98,20,34,76............,如果種子決定從4開始取數,那麼就依次開始取。直到滿足程序的需求。如果種子不變的話,那麼取得的隨機數永遠是從4開始取。一般而言,隨機種子是根據當前機器的時間來獲取的。上面說的只是一種簡單的產生偽隨機數的方法。可以作為參考。
可以去網路看一下:講的有點專業,不過還是比較全面的,下面是網址:

H. 如何評價一個偽隨機數生成演算法的優劣

偽隨機數演算法的優劣可以從以下方面考慮:

1) 隨機數分布的均勻性

2)隨機數生成速度

3)周期性(循環的周期 個人理解)

准備入門計算機的新手。還請諸位大神指正。

I. 什麼是偽隨機

結構可以預先確定,可重復產生和復制,具有某種隨機序列隨機特性的序列碼。偽隨機碼序列一般可以利用移位寄存器網路產生,該網路由R級串聯雙態器件移位脈沖產生器和模二加法器組成。該網路可以產生碼長為15的偽隨機碼。在計算機、通信系統中我們採用的隨機數、隨機碼均為偽隨機數、偽隨機碼。所謂「隨機碼」,就是無論這個碼有多長都不會出現循環的現象,而「偽隨機碼」在碼長達到一定程度時會從其第一位開始循環,由於出現的循環長度相當大,例如CDMA採用42的偽隨機碼,重復的可能性為4.4萬億分之一,所以可以當成隨機碼使用。 中文名:偽隨機碼 利用:移位寄存器網路產生 例如:CDMA採用42的偽隨機碼 特點:結構可預先確定,重復產生和復制

J. 解脫的偽隨機演算法是怎麼算的

編程語言中有偽隨機數生成器,例如,srand() 生成種子,rand() ,random() 生成隨機數。網上也可找到函數的源碼
具體生成時,要根據具體要求,編寫演算法。
例如,要求 生成的數的數值范圍,個數,是否允許重復,等等。
你上面的數,有5位的,6位的,7位的。每個數中的幾位數數值不同,高位第一位為012之一,後面位的數大於前面的數。
第十一組隨機數 我可以隨便寫一個,
例如: 0124579, 012579, 01579 都可以,
關鍵是 滿足要求的條件 -「約束條件」。

熱點內容
如何開張一個租賃伺服器 發布:2024-10-18 11:46:13 瀏覽:825
python解析json文件 發布:2024-10-18 11:29:34 瀏覽:310
編譯程序的生成程序 發布:2024-10-18 11:29:27 瀏覽:403
軌跡處理演算法 發布:2024-10-18 11:22:25 瀏覽:782
支付密碼怎麼破解 發布:2024-10-18 11:09:19 瀏覽:144
線性鏈表c語言 發布:2024-10-18 11:09:17 瀏覽:784
淘寶賣的腳本可靠嗎 發布:2024-10-18 10:54:04 瀏覽:119
數質數演算法 發布:2024-10-18 10:53:26 瀏覽:281
安卓11有的地方怎麼那麼卡 發布:2024-10-18 10:53:21 瀏覽:478
蘋果怎麼設置程序加密 發布:2024-10-18 10:52:41 瀏覽:101