繁体   English   中英

JavaScript加权随机或百分比的时间

[英]JavaScript weighted random or percent of the time

我有一个每100ms运行一次的Node.js进程(setInterval)。 我每隔x段时间就会采取一些行动。 因此,例如,2%的时间做X,10%的时间做Y,等等。

现在,我基本上是这样做的:

var rand = Math.floor(Math.random() * (1000 + 1));

if(rand > 900) {  // Do something }

if(rand > 950) {  // Do something }

问题是它非常不一致。 你想要if(rand > 900)至少接近10%的时间,但有时它可能是连续10次或根本不是。

如果我们假设100ms间隔是固定的,那么是否有人会建议更好的解决方案更准确。

谢谢!

编辑:根据Dredel博士的评论:

var count = 0;
setInterval(function(){

    if(count++ % 4 == 0) {
       console.log('25% of the time');
    }

}, 100);​

如果您的间隔是固定的,我会将您的印章舍入到最接近的百位,然后使用与您的需求相关的那些段... 100和200但不是300到1000表示2%。

如果您可以使用计数器,那么这是更明显的方法。

if(myCounter++ % 4 == 0)
    //this happens 25 percent of the time 

正如埃米尔指出的那样,概率在这里并不是正确的方法,而且我没有意识到你已经和它结婚了......听起来你正在使用它,因为你没有看到更好的激发方式x%的时间会发生一些事情。 如果我们误解你,你需要更详细地解释为什么你在这里使用赔率。

介绍一个柜台和BAM! 现在,您可以准确地把它的时间为2%!

说真的,引入某种状态是你执行“不太多次连续”政策的唯一方法。 概率/随机性无法帮助您解决此问题。 随机事件不能连续多次发生的信念是一个众所周知的神话。 事实上,2%的可能事件可能连续发生数百万次,尽管这种情况不太可能发生。

您需要添加一个约束,例如“ 我希望事件以x%概率发生,但我总是希望它在每个事件之后至少走y步 ”。

如果你想保证你的操作确实发生在一个确切的时间百分比(而不是让它成为偶然),但是你希望它们是以随机顺序选择的,那么你可以做一些这样的事情来创建一个数据结构通过所有元素进行一次迭代所需的确切结果。 然后,您随机选择其中一个结果,从数据结构中删除它,随机选择另一个结果等等......

如果您使用每个结果的适当百分比来初始化初始数据结构,那么您将根据该规则获得结果,并且对于每个完整的迭代,您将获得每个结果的所需数量,但它们将以随机顺序选择而且每次订单都会有所不同。

如果您希望该过程反复重复,您可以在每次完成一次完整迭代时启动它。

var playProbabilities = [
    {item: "A", chances: 3},
    {item: "B", chances: 2},
    {item: "C", chances: 1},
    {item: "D", chances: 2},
    {item: "E", chances: 1},
    {item: "F", chances: 1}
];

function startPlay(items) {
    var itemsRemaining = [];
    // cycle through the items list and populate itemsRemaining
    for (var i = 0; i < items.length; i++) {
        var obj = items[i];
        // for each item, start with the right number of chances
        for (var j = 0; j < obj.chances; j++) {
            itemsRemaining.push(obj.item);
        }
    }
    return(itemsRemaining);
}

function nextPlay(itemsRemaining) {
    if (!itemsRemaining.length) {
        return null;
    }
    // randomly pick one
    var rand = Math.floor(Math.random() * itemsRemaining.length);
    var result = itemsRemaining[rand];

    // remove the one we picked from the array
    itemsRemaining.splice(rand, 1);
    return(result);
}

$("#go").click(function() {
    var results = $("#results");
    var items = startPlay(playProbabilities);
    var next;
    while(next = nextPlay(items)) {
        results.append(next + "<br>");
    }
    results.append("-------------<br>");
});

在这里工作演示: http//jsfiddle.net/jfriend00/x2v63/

如果运行演示,您将看到每次运行时,它会精确生成每个结果的所需数量,但它们是按随机顺序选择的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM