2011-05-17 89 views
4

我正在尋找實現隨機數生成器的最佳方法,這將允許我控制從生成的數字返回的範圍的概率。爲了形象化我想要實現我有一個畫面:隨機數範圍的不同概率

not uniform random distribution

所以總結: 比方說,我的範圍是400在開始的時候,我想有一個獲得5%的概率數字0-20。但是在某個時候,我希望這個概率增加到50%。希望你明白這個主意。

+1

我希望獲得0-20範圍內的數字默認爲5%。將其增加到50%意味着每秒需要一次0-20的數字,其他時間則需要21-400次。你到目前爲止有什麼? – RobG 2011-05-17 01:26:01

+0

只是想找個主意。好吧,但如果我想要它是16%,例如?乍一看, – owca 2011-05-17 01:37:36

回答

3

嗯,在你的原始工作我有一個非常簡單的算法,以適當的比例在一個數組中生成範圍,然後隨機選擇一個範圍,並在該範圍內生成一個隨機數。毫無疑問,如果有必要,它可以進行優化,但它適用於我。

它看起來像很多代碼,但其中3/4是註釋,測試數據和函數,實際randomRange函數只有17行代碼。

<script type="text/javascript"> 

function randomRange(dataArray) { 

    // Helper function 
    function getRandomInRange(s, f) { 
    return (Math.random() * (f-s+1) | 0) + s 
    } 

    // Generate new data array based on probability 
    var i, j = dataArray.length; 
    var oArray = []; 
    var o; 
    while (j--) { 
    o = dataArray[j]; 

    // Make sure probability is an integer 
    for (i=0, iLen=o.probability|0; i<iLen; i++) { 
     oArray.push([o.rangeStart, o.rangeEnd]); 
    } 
    } 

    // Randomly select a range from new data array and 
    // generate a random number in that range 
    var oEnd = oArray.length; 
    var range = oArray[getRandomInRange(0, oArray.length - 1)]; 
    return getRandomInRange(range[0], range[1]); 
} 

// Test data set. Probability just has to be 
// representative, so 50/50 === 1/1 
var dataArray = [ 
    { 
    rangeStart: 0, 
    rangeEnd : 20, 
    probability: 1 
    }, 
    { 
    rangeStart: 21, 
    rangeEnd : 400, 
    probability: 1 
    } 
]; 

// Test function to show range and number is randomly 
// selected for given probability 
function testIt() { 
    var el0 = document.getElementById('div0'); 
    var el1 = document.getElementById('div1'); 
    function run() { 
    var n = randomRange(dataArray); 
    if (n <= 20) { 
     el0.innerHTML += '*'; 
    } else { 
     el1.innerHTML += '*'; 
    } 
    } 
    setInterval(run, 500); 
} 


</script> 

<button onclick="testIt();">Generate random number</button> 

<div>Numbers 0 - 20</div> 
<div id="div0"></div> 
<div>Numbers 21 - 400</div> 
<div id="div1"></div> 
+0

缺少分號;在var dataArray = [...]之後(如果您使用代碼縮小)。但這是偉大的人!非常感謝分享這個。 – Ilyssis 2012-07-23 13:15:11

+0

謝謝,修正。 :-) – RobG 2012-07-24 01:31:57

3

這聽起來像你想要的是一種生成正常(或高斯)分佈數字的方法(如果你不知道這是什麼意思,請看the Wikipedia page)。

Box-Muller transformation可用於生成正態分佈的數字對。

下面是Box-Muller轉換的極座標形式的C++實現,不應該很難轉換爲javascript。

// Return a real number from a normal (Gaussian) distribution with given 
// mean and standard deviation by polar form of Box-Muller transformation 
double x, y, r; 
do 
{ 
    x = 2.0 * rand() - 1.0; 
    y = 2.0 * rand() - 1.0; 
    r = x * x + y * y; 
} 
while (r >= 1.0 || r == 0.0); 
double s = sqrt(-2.0 * log(r)/r); 
return mean + x * s * stddev; 

其中平均值是正態分佈的均值,標準偏差是分佈的標準差。這段代碼來自我最近一直使用的MersesenneTwister C++類,你可以找到on Rick Wagner's page。您可以在this page上找到一些關於Box-Muller轉換的更多有用信息。

+0

看起來就像我正在尋找的東西。 – owca 2011-05-17 01:47:50