簡體   English   中英

Random.Next() - 找到Nth .Next()

[英]Random.Next() - finding the Nth .Next()

鑒於一直播種隨機:

Random r = new Random(0);

調用r.Next()始終生成相同的系列; 那么有沒有辦法快速發現該系列中的第N個值,而不調用r.Next() N次?

我的場景是通過r.Next()創建的大量值。 應用程序偶爾會在任意索引處從數組中讀取值。 我想通過消除數組來優化內存使用,而是根據需要生成值。 但是強制r.Next() 500萬次以模擬陣列的第500萬個索引比存儲陣列更昂貴。 是否有可能縮短你的方式到Nth .Next()值,沒有/少循環?

我不知道BCL中使用的PRNG的細節,但我的猜測是你會發現很難/不可能為系列的第N個值找到一個漂亮的,封閉形式的解決方案。

這個解決方法怎么樣:

使隨機數生成器的種子成為所需的索引,然后選擇第一個生成的數字。 這同樣是“確定性的”,並且在O(1)空間中為您提供了廣泛的范圍。

static int GetRandomNumber(int index)
{
    return new Random(index).Next();
} 

從理論上講,如果您知道確切的算法和初始狀態,您就可以復制該系列,但最終結果與調用r.next()完全相同。

根據您需要隨機數的“好”程度,您可以考慮基於線性同余生成器創建自己的PRNG,該生成器相對容易/快速生成數字。 如果您可以使用“壞”PRNG,可能還有其他算法可能更適合您的目的。 這是否比從r.next()存儲大量數字更快/更好是另一個問題。

不,我不相信有。 對於某些RNG算法(例如線性同余生成器),原則上可以在不迭代n個步驟的情況下獲得第n個值,但是Random類不提供這樣做的方法。

我不確定它使用的算法原則上是否可行 - 它是Knuth的減法RNG的變體(文檔中未公開的細節),看起來原始的Knuth RNG應該等同於某種多項式算術允許訪問第n個值的東西,但是(1)我實際上沒有檢查過這個,(2)微軟所做的任何調整都可能打破這個。

如果你有一個足夠好的“加擾”函數f那么你可以使用f(0),f(1),f(2),...作為你的隨機數序列,而不是f(0),f(f (0)),f(f(f(0)))等(后者大致是大多數RNG所做的)然后當然在你喜歡的任何一點上啟動序列是微不足道的。 但你需要選擇一個好的f,它可能比標准RNG慢。

您可以構建自己的“索引”和“隨機值”的按需字典。 這假設您每次程序運行時始終以相同的順序“請求”索引,或者您不關心每次程序運行時結果是否相同。

Random rnd = new Random(0);
Dictionary<int,int> randomNumbers = new Dictionary<int,int>();
int getRandomNumber(int index)
{
    if (!randomNumbers.ContainsKey(index))
        randomNumbers[index] = rnd.Next();
    return randomNumbers[index];
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM