JavaScript加权随机或时间百分比

JavaScript加权随机或时间百分比,javascript,node.js,random,weighted,Javascript,Node.js,Random,Weighted,我有一个Node.js进程setInterval,每100ms运行一次。我有一些行动,我想采取每x时间段。例如,2%的时间做X,10%的时间做Y,等等 现在,我基本上是这样做的: var rand = Math.floor(Math.random() * (1000 + 1)); if(rand > 900) { // Do something } if(rand > 950) { // Do something } 问题是它非常不一致。您可能希望ifrand>900的时间

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

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

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

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

if(rand > 950) {  // Do something }
问题是它非常不一致。您可能希望ifrand>900的时间至少接近10%,但有时它可能是连续的10倍,或者根本没有

如果我们假设100毫秒的间隔是固定的,有没有人会对更好的解决方案提出更精确的建议

谢谢大家!

编辑:根据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%的事件发生。如果我们误解了你,你需要更详细地解释为什么你在这里使用赔率

如果您的间隔是固定的,我会将您的邮票四舍五入到最接近的100,然后使用与您的需要相关的部分。。。100和200,但不是300-1000,代表2%

如果你能使用计数器,那么这是更明显的方法

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

正如埃米尔指出的,概率在这里不是正确的方法,我不觉得你已经和它结了婚。。。听起来你使用它是因为你没有找到更好的方法来激发x%的事件发生。如果我们误解了你,你需要更详细地解释为什么你在这里使用赔率

介绍一个计数器,然后砰!现在你可以有2%的时间拥有它

说真的,引入某种状态是强制执行不太多次连续策略的唯一方法。概率/随机性无法帮助您解决此问题。认为随机事件不可能连续发生多次的观点是一个众所周知的神话。事实上,2%的概率事件可能会连续发生数百万次,尽管可能性很小


您需要添加一个约束,例如我希望事件以x%的概率发生,但我始终希望它在每个事件后至少进行y步。

引入一个计数器并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>");
});
在此进行工作演示:


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

如果您希望确保您的操作以准确的时间百分比发生,而不是将其留给偶然的机会,但您希望以随机顺序选择它们,然后,您可以这样做,创建一个数据结构,其中包含所有元素的一次迭代的确切结果。然后,您随机选择其中一个结果,将其从数据结构中删除,随机选择另一个结果,依此类推

如果您使用每个结果的适当百分比来为初始数据结构播种,那么您将根据该规则获得结果,并且对于通过的每个完整迭代,您将获得每个结果的确切所需数量,但它们将以随机顺序选择,并且每次的顺序都不同

如果你想让这个过程一次又一次地重复,你可以直接启动它 每次完成一个完整的迭代时

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>");
});
在此进行工作演示:



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

是否不可能为您要执行的每个单独的子流程创建一个setInterval?我不确定我是否理解您的要求。随机情况下,你可能会得到一个10%的事件连续多次发生,或者根本不发生。欢迎来到概率世界这是一个疯狂的世界,受过教育的人可能不理解魔兽世界玩家威利特似乎想要控制分布,因此如果y在8次迭代中没有出现,则增加其概率,反之,如果在4次迭代中出现两次,则降低其概率。您可能还希望确保不会连续获得两个y。如果你想要的话,我相信有一个相当简单的算法。它不是完全随机的,但可能足够了。仅供参考,您可以在此处使用随机性:。正如其他人所说的,如果您希望在少量的迭代中,某个对象的时间恰好为n%,那么你不能使用随机,因为这只会给你大量迭代的预期结果。为你想执行的每个单独的子过程创建一个setInterval是不可能的吗?我不确定我是否理解你的要求。随机情况下,你可能会得到一个10%的事件连续多次发生,或者根本不发生。欢迎来到概率世界这是一个疯狂的世界,受过教育的人可能不理解魔兽世界玩家威利特似乎想要控制分布,因此如果y在8次迭代中没有出现,则增加其概率,反之,如果在4次迭代中出现两次,则降低其概率。您可能还希望确保不会连续获得两个y。如果你想要的话,我相信有一个相当简单的算法。它不是完全随机的,但可能足够了。仅供参考,您可以在此处使用随机性:。正如其他人所说,如果你想在少量的迭代中精确地获得n%的时间,那么你不能使用随机,因为这只会在大量的迭代中得到预期的结果。谢谢!所以我在上面的问题中增加了一个例子。这就是你的意思吗?如果我想在10%或2%的时间里做某件事,该怎么办?这也是一个连续运行的时间间隔,因此计数器最终会达到数亿-这种方法似乎仍然合适吗?当然。。。您可以随时重置计数器。如果你处理的是百分比,你可以在每次计数器达到100时重置它。这实际上取决于您需求的粒度。如果你需要某事发生,1%的时间你需要运行计数器到100。如果你需要它发生。百分之一的时间你需要运行它到1000。然而,如果你需要它运行1/2的时间,你的计数器永远不需要超过2:只要考虑一下我需要它的频率就可以了。虽然这不是一个随机生成器,它会以精确的比率返回值,所以1:4正好每四次出现一次,1:5正好每五次出现一次,依此类推。@RobG,我在dave的帖子中没有看到任何暗示他希望它是随机的。这似乎是他想出的解决办法,让它偶尔发生。谢谢!所以我在上面的问题中增加了一个例子。这就是你的意思吗?如果我想在10%或2%的时间里做某件事,该怎么办?这也是一个连续运行的时间间隔,因此计数器最终会达到数亿-这种方法似乎仍然合适吗?当然。。。您可以随时重置计数器。如果你处理的是百分比,你可以在每次计数器达到100时重置它。这实际上取决于您需求的粒度。如果你需要某事发生,1%的时间你需要运行计数器到100。如果你需要它发生。百分之一的时间你需要运行它到1000。然而,如果你需要它运行1/2的时间,你的计数器永远不需要超过2:只要考虑一下我需要它的频率就可以了。虽然这不是一个随机生成器,它会以精确的比率返回值,所以1:4正好每四次出现一次,1:5正好每五次出现一次,依此类推。@RobG,我在dave的帖子中没有看到任何暗示他希望它是随机的。这似乎正是他提出的解决方案,让它偶尔发生。这是一个有趣的方法,我不确定它是否适用于此应用程序-这是否可以用于在X%的时间内执行操作?@dave-是的,它可以在X%的时间内设置概率。我答案中的例子有A:30%,B:20%,C:10%,D:20%,E:10%,F:10%。你可以调整每个项目的机会数来改变它的概率。一个给定物品的概率是它的机会数除以所有机会数的总和。@RobG-我看不到任何标准
OP写的任何东西中都没有顺序项。这段代码的目的是确保每个项目都能获得公平的点击份额,即使样本量很小。这是一种有趣的方法,我不确定它是否适用于此应用程序-这是否可以用于执行X%时间的操作?@dave-是的,它可以设置为X%时间的概率。我答案中的例子有A:30%,B:20%,C:10%,D:20%,E:10%,F:10%。你可以调整每个项目的机会数来改变它的概率。一个给定项目的概率是它的机会数除以所有机会数的总和。@RobG-我没有看到OP写的任何东西中没有顺序项目的任何标准。这段代码的要点是保证每个项目都能获得公平的点击份额,即使样本量很小。