Dar*_*man 238 javascript random algorithm numbers
是否有可能获得1-100之间的随机数并保持结果主要在40-60范围内?我的意思是,它很少会超出这个范围,但我希望它主要在这个范围内......是否可以使用JavaScript/jQuery?
现在我只是使用基本的Math.random() * 100 + 1.
Blu*_*eft 397
最简单的方法是从0-50生成两个随机数并将它们加在一起.
这使得分布偏向50,同样地将两个骰子偏差朝向7滚动.
实际上,通过使用更多的"骰子" (如@Falco建议的那样),您可以更接近钟形曲线:
function weightedRandom(max, numDice) {
var num = 0;
for (var i = 0; i < numDice; i++) {
num += Math.random() * (max/numDice);
}
return num;
}
Run Code Online (Sandbox Code Playgroud)

JSFiddle:http://jsfiddle.net/797qhcza/1/
Eri*_*ert 48
你在这里有一些很好的答案,提供具体的解决方案 让我为您描述一般解决方案.问题是:
这个问题的一般解决方案是制定出位数功能所需的分布,然后应用位数功能制服源的输出.
分位数函数是所需分布函数的积分的倒数.分布函数是曲线的一部分下面积等于随机选择的项目在该部分中的概率的函数.
我举一个如何这样做的例子:
http://ericlippert.com/2012/02/21/generating-random-non-uniform-data/
其中的代码在C#中,但原则适用于任何语言; 应该可以直接使解决方案适应JavaScript.
iCa*_*mba 36
取数组等等效率不高.您应该采用一个映射,该映射采用0到100之间的随机数并映射到您需要的分布.因此,在您的情况下,您可以采用在您的范围中间获得最多值的分布.f(x)=-(1/25)x2+4x

Bit*_*ive 17
我可能会做一些事情,例如设置一个"机会",允许号码"超出界限".在这个例子中,20%的可能性是1-100,否则,40-60:
$(function () {
$('button').click(function () {
var outOfBoundsChance = .2;
var num = 0;
if (Math.random() <= outOfBoundsChance) {
num = getRandomInt(1, 100);
} else {
num = getRandomInt(40, 60);
}
$('#out').text(num);
});
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
});Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button>Generate</button>
<div id="out"></div>Run Code Online (Sandbox Code Playgroud)
小提琴:http://jsfiddle.net/kbv39s9w/
Lef*_*fty 15
几年前我需要解决这个问题,我的解决方案比任何其他答案都容易.
我在界限之间生成了3个randoms并对它们进行了平均.这会将结果拉向中心,但完全有可能到达四肢.
max*_*890 14
它看起来很愚蠢但你可以使用rand两次:
var choice = Math.random() * 3;
var result;
if (choice < 2){
result = Math.random() * 20 + 40; //you have 2/3 chance to go there
}
else {
result = Math.random() * 100 + 1;
}
Run Code Online (Sandbox Code Playgroud)
kas*_*erd 11
生成这样的随机数有很多种不同的方法.一种方法是计算多个均匀随机数的总和.您总和了多少随机数以及它们的范围将决定最终分布的外观.
你总结的数字越多,它偏向中心的次数就越多.在你的问题中已经提出使用1个随机数的总和,但是你注意到并没有偏向范围的中心.其他答案建议使用2个随机数的总和或3个随机数的总和.
通过获取更多随机数的总和,您可以获得更多偏向范围的中心.在极端情况下,你可以得到99个随机数的总和,每个数字都是0或1.这将是二项分布.(在某种意义上,二项分布可被视为正态分布的离散版本).理论上它仍然可以涵盖整个范围,但是它对中心有很大的偏见,你永远不应该期待它到达终点.
这种方法意味着您可以调整您想要的偏差.
用这样的东西怎么样:
var loops = 10;
var tries = 10;
var div = $("#results").html(random());
function random() {
var values = "";
for(var i=0; i < loops; i++) {
var numTries = tries;
do {
var num = Math.floor((Math.random() * 100) + 1);
numTries--;
}
while((num < 40 || num >60) && numTries > 1)
values += num + "<br/>";
}
return values;
}Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="results"></div>Run Code Online (Sandbox Code Playgroud)
我编写它的方式允许你设置几个变量:
loops =结果
尝试次数=函数在停止运行while循环之前尝试获得40-60之间的数字的次数
额外奖励:它使用do !!! 令人敬畏的最佳状态
你可以写一个随机值之间的映射功能[0, 1),以[1, 100]按重量.考虑这个例子:

这里,值0.95映射到之间的值[61, 100].
事实上,我们有.05 / .1 = 0.5,当映射到[61, 100],屈服81.
这是功能:
/*
* Function that returns a function that maps random number to value according to map of probability
*/
function createDistributionFunction(data) {
// cache data + some pre-calculations
var cache = [];
var i;
for (i = 0; i < data.length; i++) {
cache[i] = {};
cache[i].valueMin = data[i].values[0];
cache[i].valueMax = data[i].values[1];
cache[i].rangeMin = i === 0 ? 0 : cache[i - 1].rangeMax;
cache[i].rangeMax = cache[i].rangeMin + data[i].weight;
}
return function(random) {
var value;
for (i = 0; i < cache.length; i++) {
// this maps random number to the bracket and the value inside that bracket
if (cache[i].rangeMin <= random && random < cache[i].rangeMax) {
value = (random - cache[i].rangeMin) / (cache[i].rangeMax - cache[i].rangeMin);
value *= cache[i].valueMax - cache[i].valueMin + 1;
value += cache[i].valueMin;
return Math.floor(value);
}
}
};
}
/*
* Example usage
*/
var distributionFunction = createDistributionFunction([
{ weight: 0.1, values: [1, 40] },
{ weight: 0.8, values: [41, 60] },
{ weight: 0.1, values: [61, 100] }
]);
/*
* Test the example and draw results using Google charts API
*/
function testAndDrawResult() {
var counts = [];
var i;
var value;
// run the function in a loop and count the number of occurrences of each value
for (i = 0; i < 10000; i++) {
value = distributionFunction(Math.random());
counts[value] = (counts[value] || 0) + 1;
}
// convert results to datatable and display
var data = new google.visualization.DataTable();
data.addColumn("number", "Value");
data.addColumn("number", "Count");
for (value = 0; value < counts.length; value++) {
if (counts[value] !== undefined) {
data.addRow([value, counts[value]]);
}
}
var chart = new google.visualization.ColumnChart(document.getElementById("chart"));
chart.draw(data);
}
google.load("visualization", "1", { packages: ["corechart"] });
google.setOnLoadCallback(testAndDrawResult);Run Code Online (Sandbox Code Playgroud)
<script src="https://www.google.com/jsapi"></script>
<div id="chart"></div>Run Code Online (Sandbox Code Playgroud)
这是在该范围之外的3/4 40-60和1/4的加权解决方案.
function weighted() {
var w = 4;
// number 1 to w
var r = Math.floor(Math.random() * w) + 1;
if (r === 1) { // 1/w goes to outside 40-60
var n = Math.floor(Math.random() * 80) + 1;
if (n >= 40 && n <= 60) n += 40;
return n
}
// w-1/w goes to 40-60 range.
return Math.floor(Math.random() * 21) + 40;
}
function test() {
var counts = [];
for (var i = 0; i < 2000; i++) {
var n = weighted();
if (!counts[n]) counts[n] = 0;
counts[n] ++;
}
var output = document.getElementById('output');
var o = "";
for (var i = 1; i <= 100; i++) {
o += i + " - " + (counts[i] | 0) + "\n";
}
output.innerHTML = o;
}
test();Run Code Online (Sandbox Code Playgroud)
<pre id="output"></pre>Run Code Online (Sandbox Code Playgroud)
好的,所以我决定添加另一个答案,因为我觉得我的最后答案,以及这里的大多数答案,使用某种半统计方式获得钟形曲线型结果返回.我在下面提供的代码与掷骰子的方式相同.因此,最难获得1分或99分,但最容易获得50分.
var loops = 10; //Number of numbers generated
var min = 1,
max = 50;
var div = $("#results").html(random());
function random() {
var values = "";
for (var i = 0; i < loops; i++) {
var one = generate();
var two = generate();
var ans = one + two - 1;
var num = values += ans + "<br/>";
}
return values;
}
function generate() {
return Math.floor((Math.random() * (max - min + 1)) + min);
}Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="results"></div>Run Code Online (Sandbox Code Playgroud)
我建议使用beta发行版生成0-1之间的数字,然后进行扩展.它非常灵活,可以创建许多不同形状的分布.
这是一个快速而肮脏的采样器:
rbeta = function(alpha, beta) {
var a = 0
for(var i = 0; i < alpha; i++)
a -= Math.log(Math.random())
var b = 0
for(var i = 0; i < beta; i++)
b -= Math.log(Math.random())
return Math.ceil(100 * a / (a+b))
}
Run Code Online (Sandbox Code Playgroud)
小智 5
var randNum;
// generate random number from 1-5
var freq = Math.floor(Math.random() * (6 - 1) + 1);
// focus on 40-60 if the number is odd (1,3, or 5)
// this should happen %60 of the time
if (freq % 2){
randNum = Math.floor(Math.random() * (60 - 40) + 40);
}
else {
randNum = Math.floor(Math.random() * (100 - 1) + 1);
}
Run Code Online (Sandbox Code Playgroud)
针对这个问题的最佳解决方案是BlueRaja提出的解决方案- Danny Pflughoeft,但我认为一个更快,更通用的解决方案也值得一提.
当我必须生成满足两个要求的随机数(字符串,坐标对等)
我通常首先创建一个满足要求的数字数组(字符串,坐标对等)(在您的情况下:包含多次可能的数字的数组数组.),然后选择该数组的随机项.这样,您只需每个项目调用一次昂贵的随机函数.