在一定的时间范围内随机做一些事情

本文关键字:随机 范围内 时间 | 更新日期: 2023-09-27 18:34:58

我有一个间隔为 1000 毫秒的计时器。我想在随机时间但在给定的时间范围内做某事。例如,如果我指定的时间范围是例如 10 秒、1-10、11-20、21-30 等。这意味着在前 10 秒内,第一个时间范围 1 到 10 秒之间会随机发生一些事情。例如,可能发生在第 2 秒或第 8 秒。然后从 11 秒到 20 秒再次发生某些事情,在第二个时间范围之间的任何时间。例如,这可能是第 13 秒或第 15 秒。请注意,计时器必须是连续的,例如从 1 到 100 秒。在这里,如果我指定时间框架为 10,我们将有 10 个时间框架。1-10,11-20,21-30 ....91-100. 因为我需要知道将要发生的事件的确切时间。因此,不要认为重置计时器可以解决问题。

感谢您的回复,非常感谢带有解释的示例。

在一定的时间范围内随机做一些事情

你的问题不是很清楚,所以让我假设作为函数将发生的事情。 假设func1发生在 [1-10] 中,func2发生在 [11-20] 中,依此类推。

  • 实现一个名为 random 的函数,该函数输出bool(用于判断是否执行(。
  • 为每个时间间隔的箱定义一组标志,以跟踪我们是否已经执行了此时间段的指定函数(flag1flag2,...(。
  • 设置计时器。间隔为 1 秒
  • 定义一个全局变量 ( count (,并每个计时器将其增加 1。
  • 在此处使用一些条件:

    if(count>0 && count<=10)
    { 
       if(flag1 && random()) {func1(); flag1=false;} 
    }
    if(count>10 && count<=20)
    { 
       if(flag2 && random()) {func2(); flag2=false;} 
    }
    

等等

只需跟踪每个帧的实际偏移量,并在生成新的事件时间时将其考虑在内:

void RunEvents(TimeSpan interval, TimeSpan duration)
{
    Random random = new Random();
    TimeSpan eventOffset = new TimeSpan();
    Stopwatch sw = Stopwatch.StartNew();
    while (sw.Elapsed < duration)
    {
        TimeSpan nextEvent = eventOffset +
            TimeSpan.FromSeconds(random.NextDouble() * interval.TotalSeconds);
        TimeSpan delay = nextEvent - sw.Elapsed;
        if (delay.Ticks > 0)
        {
            Thread.Sleep(delay);
        }
        eventOffset += interval;
    }
}

换句话说,通过将上一个事件之后的上一个间隔中剩余的时间与当前间隔的开始时间以及实际间隔内的随机时间长度相加来计算nextEvent

然后,从现在到下一个事件之间等待足够的时间。

最后,更新偏移量和间隔余数,以便它们可以用于下一轮。

笔记:

  1. 以上假设您完全省略了计时器本身,而是使用上述计时器。如果这不合适,那么您应该更具体地说明计时器本身应该如何与您随机生成的事件相关联。
  2. 编辑:我有一个模糊的感觉,我可以将eventOffsetsincePrevious组合成一个值。但是这里已经很晚了,我认为这很容易留给读者作为练习。:) 我终于明白为什么这会困扰我:我根本不需要上面的sincePrevious!叹息。代码已经过编辑以纠正我的错误。
  3. 以上使用Thread.Sleep()表示延迟。恕我直言,最好使该方法async并使用Task.Delay()。但我想保持示例简单,并且无法从问题中知道处理延迟本身的最佳方法是什么。

我认为前 3 个答案中的任何一个都不对,所以让我试试:你说的是时间在滴答作响,在 N 秒的每个切片中,您希望在该切片中随机时间发生一个事件。如果是这种情况,那么只要时间是 N 秒的倍数,就获取一个介于 0 和 N 之间的随机数,并在那时生成事件。例如,在伪代码中:

time = 0
delta_time = 1 second
max_time = 100 seconds
slice_time = 10 seconds
// decide when event of first slice will occur; can't be at 0: get random # 
// in range [delta_time, slice_time]:
next_rand_time = random(delta_time, slice_time)
setup timer to fire at interval of delta_time, each time do the following (callback): 
    time += delta_time
    // is it time to fire the event yet? allow for round-off error:
    if abs(time - next_rand_time) < 0.0001:
        generate event
    // is it time to decide when next random event will be? 
    if modulo(time, slice_time) == 0: 
        // can't be on left boundary; get random # in range [delta_time, slice_time]:
        next_rand_time = time + random(delta_time, slice_time)

这 5 个变量(时间、delta_time等(很可能是使用计时器的类的数据成员,回调将是类的方法。 在您的帖子中提供一些代码以获取更多详细信息。