2

我有一个每 100 毫秒运行一次的 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 倍或根本没有。

如果我们假设 100 毫秒间隔是固定的,那么任何人都会对更好的解决方案提出建议,该解决方案会更准确。

谢谢!

编辑:基于 Dr. Dredel 的评论:

var count = 0;
setInterval(function(){

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

}, 100);​
4

3 回答 3

5

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

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

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

正如埃米尔指出的那样,概率在这里不是正确的方法,我不觉得你已经嫁给了它......听起来你正在使用它,因为你没有看到更好的挑衅方法某事发生在 x% 的时间里。如果我们对您有误解,您需要更详细地解释为什么在这里使用赔率。

于 2012-06-22T00:17:26.873 回答
1

介绍一个计数器和 BAM!现在你可以有2 % 的时间!

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

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

于 2012-06-22T00:17:39.603 回答
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/

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

于 2012-06-22T03:39:42.647 回答