【问题标题】:Return value based on probability and percentage基于概率和百分比的返回值
【发布时间】:2020-08-16 14:58:09
【问题描述】:

关于我如何在这些示例中实现概率的任何想法。

let directions = [
    {
        1: {
            left: {
                successRate: 1,
                direction: 0
            },
            top: {
                successRate: 35,
                direction: 1
            },
            right: {
                successRate: 15,
                direction: 2
            },
            bottom: {
                successRate: 5,
                direction: 3
            }
        },
    }
]
  1. 应该循环遍历属性。
  2. 循环通过上、右、下、左来检索它们的成功率值
  3. 根据与所有事物相比的成功率(也称为概率)随机检索一个方向。概率较高的应该有较高的被叫机会。

程序在 setInterval 内,并且每次间隔循环时,都假定打印值。我尝试了很多不同的方法,但我无法弄清楚。

更新我目前遇到的实际问题。

您可以忽略“未找到”。这只是一个随机字符串。数字根据概率随机生成,但在 setInterval 函数内调用 x 次后,它变为“未定义”。

代码:

let directions = [
    {
        1: {
            left: {
                successRate: 5,
                direction: 0
            },
            top: {
                successRate: 3,
                direction: 1
            },
            right: {
                successRate: 10,
                direction: 2
            },
            bottom: {
                successRate: 30,
                direction: 3
            }
        },
    }
]

var chances = [40, 30, 15, 10, 5]; 
let items = Object.values(directions[0][1]);

function chooseWeighted(items, chances) {
    var sum = chances.reduce((acc, el) => acc + el, 0);
    var acc = 0;
    chances = chances.map(el => (acc = el + acc));
    var rand = Math.random() * sum;
    return items[chances.filter(el => el <= rand).length];
}

function scanPlayerArea(){
    console.log(chooseWeighted(items, chances).direction);
}

输出:

Not found.
1
Not found.
0
Not found.
0
Not found.
2
Not found.
0
Not found.
1
Not found.
1
Not found.
0
Not found.
0
Not found.
C:\Users\Name\Desktop\Script\file.js:1351
    dir = chooseWeighted(items, chances).direction;
                                        ^

TypeError: Cannot read property 'direction' of undefined
    at scanPlayerArea (C:\Users\Name\Desktop\Script\file.js:1351:41)
    at Timeout._onTimeout (C:\Users\Name\Desktop\Script\file.js:1633:6)
    at listOnTimeout (internal/timers.js:549:17)
    at processTimers (internal/timers.js:492:7)

C:\Users\Name\Desktop\Script>

循环:

setInterval(function(){
    scanPlayerArea()
}, 50);

【问题讨论】:

  • 不,因为我已经尝试过了。它与我使用的数据类型不匹配。这是一个简单的数组,我的是一个分层的数组对象。
  • Object.values(directions[0]["1"]) 你有一个数组,剥离了两层间接层(一个单元素数组和一个单入口对象),这些层一开始就觉得不需要。无论如何,您都可以轻松地调整显示的算法以处理对象 - 构建具有所需概率的数组,然后从该加权数组中随机选择一个元素。然后用键索引到你的对象,你就完成了。现在,如果性能很重要,您需要更高级的算法,相关线程中的解决方案可以提供帮助。
  • 你是对的,但我意识到问题是不同的。我将随机化器放在 setInterval 函数中,在几次调用返回正确值后,它变成“未定义”?任何想法
  • “我尝试了很多不同的方法,但我无法弄清楚。”请至少告诉我们其中一种方法。

标签: javascript probability


【解决方案1】:

如果我理解正确,您希望根据 successRate 属性上设置的概率在每次迭代中选取一个随机方向。如果是这样,这是我能想到的一种方法:

let directions = [
    {
        1: {
            left: {
                successRate: 5,
                direction: 0
            },
            top: {
                successRate: 3,
                direction: 1
            },
            right: {
                successRate: 10,
                direction: 2
            },
            bottom: {
                successRate: 30,
                direction: 3
            }
        },
    }
];

const items = directions[0][1];

// Calculate the total rate 100%, just a sum of all the items
let totalRate = 0;
for (var key of Object.keys(items)) {
    totalRate += items[key].successRate;
}

// Calculate the coeficient of success rate for each item and save it in items
let lastCoef = 0;
for (var key of Object.keys(items)) {
  items[key].coef = lastCoef + items[key].successRate / totalRate;
  lastCoef = items[key].coef;
  console.log(key + ' coeficient: ' + lastCoef);
}

function chooseWeighted(items) {
  const randomNum = Math.random();
  for (var key of Object.keys(items)) {
    if(randomNum < items[key].coef) {
      return key;
    }
  }
}

function scanPlayerArea(){
  console.log(chooseWeighted(items));
}

setInterval(function(){
  scanPlayerArea();
}, 1000);

【讨论】:

  • 非常感谢!
猜你喜欢
  • 2013-12-24
  • 2020-10-03
  • 1970-01-01
  • 1970-01-01
  • 2020-12-09
  • 1970-01-01
  • 2021-12-21
  • 1970-01-01
  • 2019-07-25
相关资源
最近更新 更多