[英]How to get random numbers to equal a specific number in javascript?
好的,所以我的問題是我有三個隨機數生成器,我希望所有三個隨機生成的數字(從1-5生成)的值加起來為9.例如,我隨機生成一個4,a 3和a 2.再次點擊按鈕,一個5,一個3和一個1.我已經嘗試了一段時間來做這個,但只是無法搞清楚。
function statGen() { var x = document.getElementById("number"); x.innerHTML = Math.floor((Math.random() * 5) + 1); var a = document.getElementById("agl"); a.innerHTML = Math.floor((Math.random() * 4) + 1); var l = document.getElementById("lck"); l.innerHTML = Math.floor((Math.random() * 3) + 1); }
<button id="statbutton" onclick="statGen()">Get Numbers</button> <p id="main">Main:</p> <p id="number"></p> <br/> <p id="Agl">Agl:</p> <p id="agl"></p> <br/> <p id="Lck">Lck:</p> <p id="lck"></p>
我試圖通過一個循環多次運行它,直到它是數字9,但沒有一個工作。
到目前為止,所有答案都沒有良好的隨機性。 通過選擇第一個數字,然后是第二個數字,然后選擇第三個數字,你會對極端情況產生很大的偏見。
讓我用骰子示例來說明。 假設你想要擲三個骰子,它們加起來為8個。如果你一次擲出一個骰子,你最終得到的排列有1/6的幾率為[6,1,1]。 那是因為在你滾動6(概率為1/6)之后,唯一可接受的剩余數字是1和1。
實際上,[6,1,1]不是所有可接受的卷的近1/6。 例如,從3開始給出[3,1,4],[3,2,3],[3,3,2],[3,4,1]。 因此,將第3個數字作為第一個數字應該是具有6個數字的可能性的四倍。但是這些其他方法的情況並非如此!
所以有幾種方法可以獲得“好”的隨機性。 最簡單的實際上是只滾動所有三個“骰子”,如果結果不符合您的約束,則再次滾動它們。
function roll() {
return Math.floor(Math.random() * 5 + 1); //1-5 uniformly
}
function chooseNumbers() {
var x = 0, y = 0, z = 0;
while (x + y + z !== 9) {
x = roll();
y = roll();
z = roll();
}
return [x, y, z];
}
對於大多數用途來說,這將是非常快的,但你最終會丟掉相當數量的卷。 另一種選擇是枚舉(使用代碼或手動)所有可能的排列,然后使用統一的隨機數選擇索引。
var permutations = [
[5, 3, 1],
[5, 2, 2],
[5, 1, 3],
[4, 4, 1],
//...
[1, 3, 5]
];
function chooseNumbers() {
return permutations[Math.floor(Math.random() * permutations.length)];
}
最后一個隨機數r3
取決於r1
和r2
所以它被認為是隨機的。
function statGen() {
var x = document.getElementById("number");
var r1=Math.floor((Math.random() * 9) + 1);
var r2=Math.floor((Math.random() * (8-r1)) + 1);
var r3=9-r1-r2;
x.innerHTML = r1;
var a = document.getElementById("agl");
a.innerHTML = r2;
var l = document.getElementById("lck");
l.innerHTML = r3;
}
像這樣的東西? (這是偽代碼):
var first = Math.floor((Math.random() * 5) + 1);
var second = Math.floor((Math.random() * 8-first) + 1);
var third = Math.floor((Math.random() * 9 - (first+second);
如果您需要保證3個數字,前兩個的總和應該是8或更少,除非您接受0作為第3個可能的數字。
Mark Peters在他的回答中概述了兩種方法 。 第一種方法是一種強力方法:生成三個隨機數的組,直到找到一個總和為9的隨機數。第二種方法是將所有28種可能的排列制成表格,然后隨機選擇一種。
第一種方法可能更慢,第二種方法會消耗更多內存。 只要您只需要執行一次,並且三個數字所需的總和很小(如9),那么您使用哪一個並沒有多大區別。
但是,如果所需的總和很大,則可能需要采用不同的方法。 假設,所需金額為100萬。 蠻力方法可能很慢。 列表所有排列可能會消耗太多內存(或磁盤空間,具體取決於實現)。
排列的總數是整數1
到最大可能值的總和。 可以使用數學堆棧交換中的這個等式快速計算該總和:
取第一個數字和最后一個數字的平均值,然后乘以數字的數量。
因此,在這種情況下,排列總數將近1,000,000 x 500,000
; 大約500,000,000,000
個排列。
因此,我們不是計算所有可能的排列,而是生成一個隨機數n
並在給定所需總和的情況下僅計算第n個排列:
function getPermutation( n, requiredSum) {
var remainder = n;
var step = requiredSum - 2;
var firstNumber = 1;
while(remainder > step){
firstNumber++;
remainder -= step;
step--;
}
var secondNumber = remainder;
var thirdNumber = requiredSum - firstNumber - secondNumber;
return [ firstNumber, secondNumber, thirdNumber ];
}
這里的例子:
$(document).ready( function(){ $("button").click( function() { $("div").text( JSON.stringify( get3Numbers(1000000) ) ); }); }); function get3Numbers(requiredSum){ var maximum = requiredSum - 2; var permutations = maximum * ( (maximum + 1.0) / 2.0); var randomNumber = Math.floor((Math.random() * permutations) + 1); var threeNumbers = getPermutation(randomNumber, requiredSum); var sumOfNumbers = threeNumbers[0] + threeNumbers[1] + threeNumbers[2]; return { threeNumbers: threeNumbers, total: sumOfNumbers }; } function getPermutation( n, requiredSum) { var remainder = n; var step = requiredSum - 2; var firstNumber = 1; while(remainder > step){ firstNumber++; remainder -= step; step--; } var secondNumber = remainder; var thirdNumber = requiredSum - firstNumber - secondNumber; return [ firstNumber, secondNumber, thirdNumber ]; }
div { border: 1px solid silver; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div> </div> <button>Get three numbers!</button>
這是一種方法。
function statGen() { var x = document.getElementById("number"); var firstNumber = Math.floor((Math.random() * 5) + 1); x.innerHTML = firstNumber; var a = document.getElementById("agl"); if (firstNumber == 5) { var secondNumber = Math.floor((Math.random() * 4) + 1); } else { var secondNumber = Math.floor((Math.random() * 5) + 1); } a.innerHTML = secondNumber; var l = document.getElementById("lck"); l.innerHTML = 9-(firstNumber + secondNumber); }
<button id="statbutton" onclick="statGen()">Get Numbers</button> <p id="main">Main:</p> <p id="number"></p> <br/> <p id="Agl">Agl:</p> <p id="agl"></p> <br/> <p id="Lck">Lck:</p> <p id="lck"></p>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.