簡體   English   中英

提升Mersenne Twister:如何使用多個值種子?

[英]Boost Mersenne Twister: how to seed with more than one value?

我正在使用boost mt19937實現進行模擬。

模擬需要是可重復的,這意味着以后存儲並可能重復使用RNG種子。 我正在使用windows crypto api生成種子值,因為我需要種子的外部源,而不是因為任何特殊的隨機性保證。 任何模擬運行的輸出都會有一個包含RNG種子的注釋 - 因此種子需要相當短 另一方面,作為模擬分析的一部分,我將比較幾次運行 - 但為了確保這些運行實際上是不同的,我需要使用不同的種子 - 所以種子需要足夠長避免意外碰撞

我已經確定64位播種應該足夠了; 在大約2 ^ 32次運行后,碰撞的幾率將達到50% - 這個概率足夠低,以至於它引起的平均誤差對我來說可以忽略不計。 僅使用32位種子很棘手; 在2 ^ 16次運行后,碰撞的可能性已達到50%; 這對我的口味來說有點太可能了。

不幸的是,增強實現要么是帶有完整狀態向量的種子 - 這太長,太長 - 或者是一個32位無符號長 - 這並不理想。

如何為超過32位但小於滿狀態向量的發生器播種? 我試着填充矢量或重復種子來填充狀態向量,但即使粗略地看一下結果也表明這會產生不良結果。

看看mersenne_twister模板的提升源

  void seed(UIntType value)
  {
    // New seeding algorithm from 
    // http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html
    // In the previous versions, MSBs of the seed affected only MSBs of the
    // state x[].
    const UIntType mask = ~0u;
    x[0] = value & mask;
    for (i = 1; i < n; i++) {
      // See Knuth "The Art of Computer Programming" Vol. 2, 3rd ed., page 106
      x[i] = (1812433253UL * (x[i-1] ^ (x[i-1] >> (w-2))) + i) & mask;
    }
  }

對於mt19937, UIntTypeuint32_tw是32.對於64位種子,也許你可以使用低32位來計算狀態( x )和高32位的每個偶數索引來計算狀態的奇數索引,使用那個算法。

(雖然這是貨物崇拜的建議)

你的假設是錯誤的。 對於模擬,您不需要加密強大的種子。 事實上,使用種子1,2,3,4,等等通常是一個更好的主意。 Mersenne Twister的輸出值將是不相關的,但沒有人會懷疑你是否采摘了種子以獲得所需的模擬輸出。

對於其他確實需要的人來說,一種簡單的方法是丟棄生成的第一個(種子>> 32)值。 這為您提供了log2(種子>> 32)額外的狀態位。 但是,如果您需要一些額外的位,它只能有效地工作。 以這種方式添加32位可能太慢了。

更快的算法是為良好的隨機生成器生成完整的狀態向量。 由於所得狀態向量中的隨機性有限,問題中提到的解決方案(重復或填充)不太好。 但是如果你從mersenne_twister(seed1) ^ mersenne_twister(seed2)的輸出填充初始狀態向量,這根本不是問題。

暫無
暫無

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

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