使用Random的兩個誤區

2021-04-23 21:31:31 字數 2374 閱讀 3710

.

隨機數的問題(c++**).

c/c++ code

for

(inti =

0;i<

n;++

i)

這裡很明顯他是想輸出一串小於100的隨機的數列.可是執行結果輸出的卻是類似

97,97,97,97,....97,30,30,30,30,30,30,30,30,30,30,30,30,....,27,27,27,27,27,27,....

的序列.很明顯這樣完全看不出有任何的隨機性.這是由於他對c的rand函式不理解導致

的錯誤用法.而這兩天逛c#區我也同樣看到了幾個類似的錯誤用法(c和c#的rand從大體

的原理上差不多).想想自己初學的時候類似的錯誤犯得也不少.所以自己下去查了寫資料

總結了在隨機數使用上的一些錯誤的用法.希望能對初學者有所幫助.

先來說說隨機數演算法的實現.借用c數值演算法裡的一句話:利用計算機,這種人類所設計的

各種機器中最精確,最能做出確切判斷的機器,來產生"隨機數",這看上去有些自相矛盾.甚至在

概念上是講不通的.任何程式必將產生完全可以預計的結果.因而不是真正的"隨機數".

現在各種語言中的隨機數產生函式所產生的"隨機數",實際上被稱之為"偽隨機數".可以將

整個隨機數函式看做這樣乙個表示式:

a = r(s)

其中r是隨機函式,s是種子.a是乙個數列.即對於任意乙個種子s,經過r的計算後,總有乙個確定

的數列a與之對應.而當在c#裡呼叫var rnd = new random (s)或在c裡呼叫srand(s)實質上

所做工作之一就是設定這個種子.而rnd.next();或rand()只不過是在a上取下乙個元素而已.當然實

際的實現不可能事先計算乙個數列a,所以rand()相當於由s計算出下乙個數字s',然後將s'作為新

的種子賦值給s,最後將s'作為結果返回.

接下來就是兩種常見的錯誤用法了:

c# code

for

(inti=

0;i<

n;++i),

",rnd.next());

}

這樣使用隨機數產生器只會產生乙個固定的常數n.

因為每次都用同乙個種子初始化了隨機數產生器後呼叫了next().

所取得的都是數列a上的第乙個元素.而這個元素的值肯定是固定

的(當然n取什麼值要看隨機函式的實現而定).

而第二種情況就更常見了:

c# code

for

(inti=

0;i<

n;++i),

",rnd.next());

}

這樣呼叫應該是希望通過時間的不同來達到隨機的效果;但是得到的結果就和我那位朋友一樣.會是形似

97,97,97,97,....97,30,30,30,30,30,30,30,30,30,30,30,30,....,27,27,27,27,27,27,....

的一串數列.這是因為windows系統時鐘的更新頻率大概在10ms左右.而這個for迴圈的執行顯然要快

得多.於是在一段執行時間內environment.tickcount (random的預設種子)或是c的time函式返回的

都是同乙個值.從而導致rnd.next在一段時間內返回乙個常數.

所以正確的用法應該將隨機數產生器的初始化移出迴圈:

c# code

var rnd 

=new

random ();

//用系統時間作為種子

for(

inti=0

;i<

n;++i),

",rnd.next());

}

就個人習慣來說.在乙個經常用到隨機數的程式中,我會在main中就初始化乙個全域性的隨機數產生器,在

之後要用到隨機數的地方就直接呼叫next,而不用每次都構造乙個random.

random rnd = new random();

比如說輸出1-100不重複的隨機數

c# code

list

<

int>

list

=new

list

<

int>

();for

(inti=

0;i<

100;i++)

list.add(value);

}

然後輸出list

差分線Layout的兩個誤區

誤區一 認為差分線可以相互之間耦合,所以可以相互之間提供回流路徑,不需要地作為回流路徑 其實在訊號回流分析上,差分走線和普通的單端走線的機理是一致的,即高頻訊號總是沿著電感最小的迴路進行回流。最大的區別在於差分線除了有對地的耦合之外,還存在相互之間的耦合,哪一種耦合強,哪一種就成為主要的回流通路。一...

使用ReentrantLock兩個方法的互斥訪問

現在有多個執行緒需要對兩個方法都進行訪問 乙個方法名為test1,乙個方法名為test2 但是有個要求 同乙個時間只能兩個方法互斥訪問,而且兩個方法可能在不同的類裡面。就是多個執行緒只要有乙個執行緒訪問test1方法,那麼其他執行緒test1和test2方法都不能訪問,相反一樣。可能有人會想到syn...

VO的兩個使用技巧

在as3中會經常使用vo 值物件 尤其是在cairngorm之類的框架中。下面是我在工作中使用vo而總結出的兩個使用技巧,與大家分享。一 可用遍歷方式賦值。如下面 package vo 如果vo的屬性與其它物件的屬性一一對應。在轉換時就可以用遍歷賦值。如下面 我們將xml屬性解析成vo屬性。var ...