Создание функции Javascript, которая возвращает случайные целые числа, но с заданным распределением /"весом"
У меня есть массив значений:
var my_arr = [/*all kinds of stuff*/]
У меня есть функция, которая генерирует случайное число, которое я использую в качестве индекса элемента в my_arr
...
var RandomFromRange = function (min,max)
{
return Math.floor(Math.random()*(max-min+1)+min);
};
... чтобы я мог делать такие вещи:
my_arr[RandomFromRange(0,my_arr.length)];
Что я хочу сделать, это обозначить определенные элементы в my_arr
как имеющий "приоритет", так что RandomFromRange
возвращает 5, скажем, 25% времени, возвращает 4, 14% времени и возвращает любое другое число...
(100 - 25 - 14)/(my_arr.length - 2)
...% времени.
В ходе моего исследования я наткнулся на несколько постов , в которых описываются похожие проблемы, но их ответы отсутствуют в Javascript, и мне, увы, не хватает математики, чтобы понять их общие принципы. Любой совет будет принят во внимание.
1 ответ
Это может быть не так точно, как вы ищете, но это, безусловно, работает. По сути, этот код возвращает случайное число, указанное из min и max, как ваше, но только после обращения к приоритетным числам на основе предоставленного шанса.
Сначала мы должны расставить приоритеты ваших приоритетных номеров в коде. Если по вашим приоритетным номерам нет попадания, то мы переходим к обычному ГСЧ.
//priority = list of numbers as priority,
//chance = the percentage
//min and max are your parameters
var randomFromRange = function (min,max,priority,chance)
{
var val = null; //initialize value to return
for(var i = 0; i < priority.length; i++){ //loop through priority numbers
var roll = Math.floor(Math.random()*100); //roll the dice (outputs 0-100)
if(chance > roll){ ///check if the chance is greater than the roll output, if true, there's a hit. Less chance value means less likely that the chance value is greater than the roll output
val = priority[i]; //make the current number in the priority loop the value to return;
break; //if there's a hit, stop the loop.
}
else{
continue; //else, keep looping through the priority list
}
}
//if there is no hit to any priority numbers, return a number from the min and max range
if(val == null){
val = Math.floor(Math.random()*(max-min+1)+min);
}
//return the value and do whatever you want with it
return val;
};
document.getElementsByTagName('body')[0].onclick = function (){
console.log(randomFromRange(0,10,[20,30],50));
}
<!DOCTYPE html>
<html>
<body style='height: 1000px; width: 100%;'></body>
<script></script>
</html>
Этот код применяет один шанс ко всему массиву номеров приоритетов. Если вам нужны отдельные шансы для каждого числа в списке приоритетов, мы должны изменить структуру и изменить параметры в единый массив объектов, который содержит что-то вроде
var priorityList = [{num: 4, chance: 25},
{num: 5, chance: 12}]
так далее