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

时间:2012-06-22 00:15:08

标签: javascript node.js random weighted

我有一个每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);​

3 个答案:

答案 0 :(得分:4)

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

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

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

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

答案 1 :(得分:0)

介绍一个柜台和BAM!现在你可以<%>完全 2%的时间!

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

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

答案 2 :(得分:0)

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

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

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

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/

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