2013-10-28 28 views
2

我一直生成無偏隨機數通過扔掉偏差範圍內的任何數字。與此相似漂浮一個安全的替代產生一個無偏的隨機數

int biasCount = MAX_INT % max 
int maxSafeNumber = MAX_INT - biasCount; 
int generatedNumber = 0; 

do 
{ 
    generatedNumber = GenerateNumber(); 

} while (generatedNumber > maxSafeNumber) 

return generatedNumber % max; 

今天一個朋友告訴我,他如何生成的數字轉換成浮點數,則乘以產生的隨機數,打擊最大。

float percent = generatedNumber/(float)MAX_INT; 
return (int)(percent * max); 

這似乎通過首先不必使用模量來解決偏差問題。它看起來也簡單而快速。 爲什麼浮動方法不會像第一個那樣安全(沒有偏見),是否有任何理由?

+0

你爲什麼認爲它可能不安全*? – Raedwald

+0

最好的方法是使用您的語言提供的範圍隨機。例如,C++提供了包含這種功能的''。 – Adam

+0

「安全」可能不是您要查找的術語。只要說「沒有偏見」。 – jamesdlin

回答

4
  • 浮子方法與地板(即你的鑄造)引入了一個偏壓 對在範圍的最大值。

    爲了返回maxgeneratedNumber == MAX_INT必須爲真。 所以max有概率1/MAX_INT,而在 範圍內的所有其他號碼有概率max/MAX_INT

  • 正如亨利指出,也有走樣的問題,如果MAX_INT 不是max的倍數。這使得範圍內的某些值可能比其他值更可能是 。 maxMAX_INT之間的差異越大,此偏差越小。

(假設你得到的,和想要的,均勻分佈。)

這從GoingNative 2013呈現由斯蒂芬T. Lavavej越過了很多與隨機數,包括這些範圍方案常見的謬誤。這是C++的實施方式中爲中心,但所有概念沿用到任何語言: http://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful

1

浮子方法可能甚至不產生均勻分佈的輸出編號當輸入數字是均勻分佈的。要查看分解的位置,請使用一些小數字例如MAX_INT = 8

當MAX_INT很大時它變得更好,但它幾乎從來都不是完美的。