Box-Muller 算法隱含的原理非常深奧,但結果卻是相當簡單。如果您在 [0,1) 值域內有兩個一致的隨機數字 U1 和 U2(如本專欄中第一部分所述),則您可以使用以下兩個等式中的任一個算出一個正態分布的隨機數字 Z:
Z = R * cos( θ )
or
Z = R * sin( θ )
其中,
R = sqrt(-2 * ln(U2))
and
θ = 2 * π * U1
正態值 Z 有一個等于 0 的平均值和一個等于 1 的標準偏差,您可使用以下等式將 Z 映射到一個平均值為 m、標準偏差為 sd 的統計量 X:
X = m + (Z * sd)
以 NextGaussian 方法實現高斯類的最簡單方法由圖 6 中的代碼表示。
我使用的是 Math.Cos 版本,但我本完全可以輕松地使用 Math.Sin 版本。該實現代碼雖然可行,但效率很低。由于 Box-Muller 算法可利用 sin 或 cos 中的任一個函數計算正態分布的 Z 值,因此我倒不如同時計算兩個 Z 值,保存第二個 Z 值,然后在第二次調用 NextGaussian 方法時可以檢索所保存的值。此類實現方法如圖 7 所示。
盡管該方法可行性很好,但也存在一些低效性。使用 Math.Sin、Math.Cos 和 Math.Log 方法進行計算會降低性能。一種提高效率的巧妙方法是使用數學技巧。如果您檢查一下 R 和 θ 的定義,會發現它們與某單位圓內某隨機點的極坐標相對應。該數學技巧就是計算單位正方形內某隨機點的坐標(避免了調用 Math.Sin 和 Math.Cos 方法)并確定該隨機點是否在單位圓范圍內。如果是這樣,我們就可以使用這組坐標;如果不是這樣,則我們可計算一組新的隨機坐標,然后重試一次。約有 78% 的隨機生成坐標都在單位圓范圍內,這提供了更好的性能,但顯然要影響到清晰性。
圖 8 中例示了單位正方形技巧。Box-Muller 基本算法將選擇一個極坐標為 (R, θ) 并保證在單位圓范圍內的點。您也可以在包圍單位圓的單位正方形內選擇矩形坐標;點 (x1, y1) 在單位圓范圍內,但是點 (x2, y2) 則在單位圓范圍之外。圖 9 說明了單位正方形方法的實現。

圖 8 單位正方形技巧
在軟件測試場景中,性能通常不是主要的考慮因素,因此我所提到的三種實現方法都適用。但在軟件開發中,特別是在進行模擬時,性能就成為一個主要問題。盡管 Box-Muller 算法執行起來既高效又相對簡單,但是也有其他替代算法可生成正態/高斯偽隨機數字。有一種高效的替代方法稱為 ziggurat 方法。

返回頁首
總結
讓我進行一下簡單總結。生成隨機測試用例輸入數據是基本的軟件測試技能。.NET Framework 包含一個 System.Random 類,可用于生成某一特定值域內的統一分布的整數型或浮點型偽隨機數字。需要注意的主要問題就是要確保正確指定值域的端點值。
可使用 Wald-Wolfowitz 檢驗方法來分析包含兩個符號的模式以證明它是隨機生成的模式。您可使用此檢驗方法分析隨機測試用例輸入數據或分析所測試系統的輸出數據。
最佳通用混排算法稱為 Fisher-Yates 算法。它非常簡單并且幾乎不需要使用另一種方法。但即使正確算法中存在一絲微小偏差都可能導致算法看似正確但卻存在重大錯誤。
可使用 Box-Muller 算法生成正態分布的偽隨機數字。Box-Muller 算法隱含的數學原理非常深奧,但實現過程卻異常簡單。有幾種方法可用于實現 Box-Muller 算法,但都以降低效率來提高清晰性。
請將您的疑問和意見通過 testrun@microsoft.com 發送給 James。
James McCaffrey 博士供職于 Volt Information Sciences Inc.,在那里他負責管理 Microsoft 的軟件工程師的技術培訓。他已經為多種 Microsoft 產品效過力,包括 Internet Explorer 和 MSN Search?赏ㄟ^ jmccaffrey@volt.com 或 v-jammc@microsoft.com 與 James 聯系。
文章來源于領測軟件測試網 http://www.kjueaiud.com/