簡體   English   中英

如何影響 Math.Random 使數字更有可能出現?

[英]How to Influence Math.Random to Make Numbers More Likely?

我試圖弄清楚如何影響Math.random()以便timesSinceLastSelected的計數器具有更高數字的項目被選中的機會更高。

例如,如果“item1”的 timesSinceLastSelected 為 4,而“item2”的 timesSinceLastSelected 為 3,則“item1”可能有 75% 被選中,但“item2”仍有 25% 的機會,即使您不選擇不知道數組中有多少項。

let arr = [{ //Unknown number of items
    "name": "item1",
    "deselected": false,
    "favourite": false,
    "timesSinceLastSelected": 0
  },
  {
    "name": "item2",
    "deselected": false,
    "favourite": true,
    "timesSinceLastSelected": 0
  },
  {
    "name": "item3",
    "deselected": true,
    "favourite": false,
    "timesSinceLastSelected": 0
  },
  {
    "name": "item4",
    "deselected": true,
    "favourite": true,
    "timesSinceLastSelected": 0
  }
];

$('#button').click(function() {
  // Selecting only the items where deselected = false
  let filter_deselected = arr.filter(val => val.deselected === false);
  // Selecting only the items where favourite = true
  let filter_favourite = filter_deselected.filter(val => val.favourite === true);

  // How do I make timesSinceLastSelected with higher numbers more likely?

  if (Math.round(Math.random() * 10 > 5)) { // Selecte random item
    var selected = Math.floor(Math.random() * filter_deselected.length);
  } else { // Select random favourite item
    var selected = Math.floor(Math.random() * filter_favourite.length);
  }


  // Adding 1 to every item's counter
  arr.forEach(function(val) {
    val.timesSinceLastSelected++;
  });
  // Returning the selected item's counter back to 0
  filter_deselected[selected].timesSinceLastSelected = 0;
  // Logging the randomly selected item
  console.log(filter_deselected[selected]);
});

https://jsfiddle.net/knsfr2xh/

您可以獲得未選擇計數的總和,並獲得一個隨機數,直到總和並獲得該項目。

然后更新未選中的並重置選中的項目。

開始時,給所有項目一個以進行平均分配。

 const getRandom = () => { let sum = items.reduce((s, { timesNotSelected }) => s + timesNotSelected, 0), random = Math.random() * sum, item = items.find(({ timesNotSelected }) => (random -= timesNotSelected) <= 0); items.forEach(o => o.timesNotSelected = o === item? 1: o.timesNotSelected + 1) return item; }, items = [{ id: 1, timesNotSelected: 1 }, { id: 2, timesNotSelected: 1 }, { id: 3, timesNotSelected: 1 }, { id: 4, timesNotSelected: 1 }]; console.log(getRandom().id); console.log(items); console.log(getRandom().id); console.log(items); console.log(getRandom().id); console.log(items); console.log(getRandom().id); console.log(items); console.log(getRandom().id); console.log(items); console.log(getRandom().id); console.log(items); console.log(getRandom().id); console.log(items); console.log(getRandom().id); console.log(items); console.log(getRandom().id); console.log(items); console.log(getRandom().id); console.log(items);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

const getSum = (data, key) => data.reduce((sum, { [key]: n }) => sum += (n + 1), 0);

const randomThreshold = (data, key) => ~~(Math.random() * getSum(data, key));

const randomElement = (data, key, threshold = null, total = 0, i = 0) => {
  const datum = data[i];
  const newTotal = total + datum[key] + 1;
  const newThreshold = threshold || randomThreshold(data, key);
  return newTotal >= newThreshold ? datum : randomElement(data, key, newThreshold, newTotal, i + 1);
}

像這樣使用:

console.log(randomElement(items, 'timesSinceLastSelected').name)

 const items = [ { "name": "item1", "deselected": false, "favourite": false, "timesSinceLastSelected": 4 }, { "name": "item2", "deselected": false, "favourite": true, "timesSinceLastSelected": 3 }, { "name": "item3", "deselected": true, "favourite": false, "timesSinceLastSelected": 2 }, { "name": "item4", "deselected": true, "favourite": true, "timesSinceLastSelected": 1 } ]; const getSum = (data, key) => data.reduce((sum, { [key]: n }) => sum += (n + 1), 0); const randomThreshold = (data, key) => ~~(Math.random() * getSum(data, key)); const randomElement = (data, key, threshold = null, total = 0, i = 0) => { const datum = data[i]; const newTotal = total + datum[key] + 1; const newThreshold = threshold || randomThreshold(data, key); return newTotal >= newThreshold? datum: randomElement(data, key, newThreshold, newTotal, i + 1); } for (let i = 0; i < 10; i++) { console.log(randomElement(items, 'timesSinceLastSelected').name); }

基於這篇文章。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM