Создание функции 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}]

так далее

Другие вопросы по тегам