Sql-Server

如何從 RAND 函式(或其他地方)獲得滿意的隨機數?

  • June 21, 2017

我正在創建一個偽隨機數據集供應用程序使用者進行訓練。

我很驚訝如果我用 1、2、3 等為 RAND() 函式播種,我從播種函式得到的結果幾乎相同。但是,當未提供種子時,這似乎是“適當隨機”但可重複的值。

SELECT   RAND(1) AS R1A, RAND() AS R1B, RAND(2) AS R2A, RAND() AS R2B,
        RAND(3) AS R3A, RAND() AS R3B, RAND(4) AS R4A, RAND() AS R4B

0.713591993212924

0.472241415009636  

0.713610626184182  

0.217821139260039  

0.71362925915544  

0.963400850719992  

0.713647892126698  

0.708980575436056

乍一看,我似乎可以評估 RAND(@seed) 並丟棄結果,然後評估 RAND() 以獲得我的訓練數據的幾個真正“隨機”的數字——到目前為止,我計劃每條記錄使用四個;我可能還需要一些。

這個計劃能正常運作嗎?而且,我在這裡看什麼?而且,它應該在文件中嗎?我還沒有找到它。

文件說明了這一點,這可能是一個線索:

RAND 函式是一個偽隨機數生成器,其操作方式類似於 C 執行時庫 rand 函式。如果沒有提供種子,系統會生成自己的可變種子數。

C 中的 rand 函式是否會為類似的種子輸入產生類似的輸出?

我認為文件還可以更清楚地說明 RAND(@number) 後跟 RAND() 總是生成相同的數字。但這就是我想要的,也是任何有經驗的電腦程序員所期望的。

我想我可以用從https://www.random.org/獲得的隨機數據鍵填充一個表以 用於此目的 - 但這有缺點。

更新,暫定結論

我對 RAND() 有以下結論,現在我想我會繼續下去,但要記住替代方案。

RAND(@int) 使用給定的整數值設置隨機數生成器的種子,並返回在統計上獨立的浮點結果,因為 RAND(@int) 和 RAND(@int+1) 產生的結果幾乎完全相同結果。

當然,RAND(@int) 總是產生相同的結果。

RAND(-@int) 和 RAND(@int) 產生相同的結果。

RAND(0) 是一個例外:可能還有其他例外。RAND(0) 總是產生結果 0.943597390424144,但它與 RAND(1) 的結果不同。

在 RAND(@int) 之後呼叫 n 次 RAND() 總是產生相同的 n 個數字。如果我們稱第 n 個數字為“rand(@int, @n)” -

CREATE PROCEDURE sproc_rand(@seed int, @nth int, @rand float OUTPUT) AS
SET @rand = RAND(@seed);
WHILE ( @nth > 0 ) BEGIN SET @rand = RAND(); SET @nth = @nth - 1; END

rand(@int, @n) 和 rand(@int+1, @n) “模 1” 的區別 -

(1.0 + rand(@int, @n) - rand(@int+1, @n) % 1

是一個常數或接近常數;對於@n = 1,它大約是 0.75。對於@n = 5,它是 0.991。對於@n = 6,它是 0.91。對於@n = 100,它是 0.83。

所以,不,當使用簡單的遞增種子時,這些不是好的“隨機”數字——儘管它們對於@n IN (1, 2, 3, 4) 反彈得很好。

我現在考慮的緩解措施不是使用 RAND(row_id) 但是,

RAND(row_id * @factor_1 + @factor_2)

其中@factor1 和@factor2 是常數項,@factor_1 約為 10,000。而對於不同的項目,不同的因素。

到目前為止,如果我想要可重複的結果,另一種可用的方法(除了乘法逆的東西,我還不太了解)是創建一個表並用其他方法之一的非重複隨機數填充它,然後在需要時從該表中提取數字。

提供“種子”的唯一原因是,如果RAND()您想要完全相同的(偽)隨機值序列用於測試目的。

只需在沒有種子的情況下呼叫它,這對於大多數用途來說已經足夠了。

如果您確實需要一個可預測的序列,並且您只是對起始(隨機)值不滿意,那麼RAND()將種子從 -2,147,483,648 一直到 2,147,483,647(整數範圍),所以嘗試一些相差超過 1 的種子或 2。

最後,如果您使用的是 SQL 2008 或更高版本,您還可以選擇考慮CRYPT_GEN_RANDOM(警告,它返回一個 varbinary,而不是浮點數,因此您可能需要稍微更改您的程式碼):看這個文章中的一些分歧和討論

引用自:https://dba.stackexchange.com/questions/175911