所以,我正在尝试创建一种ai...。而我陷入了这个问题。
让我们假设我们有四个选择。
a。 -23 b。 -10 C。 +4 d。 +80
我必须随机选择上述选项中的1个...但是结果不应完全是随机的。具有较高价值的期权必须具有更大的结果机会,而否定期权必须具有较低的结果机会。
我需要一个方程式来完成这个任务!
通过我在js中执行此操作的方式
var a=-23;
var b=-10;
var c=4;
var d=80;
var optiontochoose=(equation which choose an option randomly by giving more preference to option with greater values)
答案 0 :(得分:2)
您可以将变量放入数组中,通过多次选择想要的变量来权衡选项,然后在数组长度范围内选择一个随机数。
var optionsArray = [a, b, b, c, c, c, d, d, d, d];
var chosenOption = optionsArray[Math.round(Math.random()*optionsArray.length)];
答案 1 :(得分:1)
我绝对同意@user11260787。据我所知,增加被选择价值的机会的唯一方法是增加其在源数据中的存在。
考虑到您希望使用一些权重来按比例增加机会,我会提出以下解决方案:
//source values along with corresponding weights,
//increasing proportionally pick-up probability
const src = [
{value: -23, chance: 3},
{value: -10, chance: 5},
{value: 4, chance: 10},
{value: 80, chance: 20}
];
//pick randomly, considering weights
const weightedRand = src => src.map(entry => (new Array(entry.chance)).fill(entry.value)).flat()[Math.floor(Math.random()*src.reduce((chanceTotal, item) => chanceTotal+=item.chance, 0))];
//do test run for 1M times to check outcome
const outcome1M = {'80':0,'4':0,'-10':0,'-23':0};
[...Array(1000000)].forEach(run => outcome1M[weightedRand(src)]++);
console.log(Object.fromEntries(Object.entries(outcome1M).map(entry => [entry[0],entry[1]/1000000])));
.as-console-wrapper {max-height:100% !important; top: 0}
答案 2 :(得分:1)
首先,您可以将这些值视为百分比值(即使未提及),并采用线性概率,然后将值的25
(100 / length
数组)。
然后取和并归一化给定数据以生成array
的随机索引。
function getRandomFn(percent) {
var parts = percent.map((p, _, { length }) => (100 + p) / length),
sum = parts.reduce((a, b) => a + b),
normalized = parts.map((s => v => s += v / sum)(0));
return () => normalized.findIndex((r => v => r < v)(Math.random()));
}
var array = ['a', 'b', 'c', 'd'],
randomIndex = getRandomFn([-23, -10, 4, 80]),
l = 1e6,
count = Object.assign(...array.map(k => ({ [k]: 0 }))),
index;
while (l--) {
index = randomIndex();
count[array[index]]++;
}
console.log(count);
答案 3 :(得分:0)
这是另一种选择。此解决方案的工作方式是首先移动整个数字列表,以使列表中的最小值等于0。然后向每个值添加百分比或静态值。将所有值求和,然后根据此总数选择一个随机值。
function pickSemiRandom(values) {
if (!values.length) return; // guard against empty arrays
var min = Math.min(...values),
max = Math.max(...values),
diff = max - min,
diffZero = min - 0,
percentage = diff * 0.20,
shifted = values.map(nr => nr - diffZero + percentage),
// ^^^^^^^^^^^^
// Offset each numbers to give the minimum value more than 0%
// change of being picked. The higher the percentage the less
// influence each value by itself has. An ofset of 0 will
// result in a 0% pick chance for the minimum value. You can
// also change this into a static value instead of a percentage
// of the difference between minimum and maximum value.
total = shifted.reduce((sum, nr) => sum + nr, 0),
randomNr = Math.random() * total;
for (let index = 0; index < values.length; index++) {
randomNr -= shifted[index];
if (randomNr < 0) return values[index];
}
console.error("for-loop should aways return");
}
var results = new Array(100).fill([-23, -10, 4, 80])
.map(values => pickSemiRandom(values));
// log results
console.log(results.join(", "));
console.log(results.reduce((counter, result) => {
counter[result] = (counter[result] || 0) + 1;
return counter;
}, {}));
您可以调整percentage
的值以更改值分布。