一段时间内随机事件的数量

时间:2016-03-11 19:44:51

标签: c algorithm

我需要跟踪给定时间段内随机事件的数量。我可以检测到事件的最大速率是每秒一次,我需要能够提供过去30分钟内的事件数。

我对此算法的第一个攻击是拥有一个数组,该数组将以秒为单位保存时间戳。每次发生新事件时,所有时间戳都会向下移动,新事件将放置在阵列的前面。当请求事件数量时,我删除超过30分钟的所有事件,然后返回结果计数。

time_t event_stamps[60 * 30];
unsigned event_count;

void events_put()
{
    time_t new_event_time = SomeCallToGetTheCurrentTimeInSeconds();

    /* Shift values down the array to make space for the new value at index 0 */
    int i;
    for(i = sizeof(event_stamps) / sizeof(event_stamps[0]); --i > 0; )
    {
        event_stamps[i] = event_stamps[i-1];
    }

    event_stamps[0] = new_event_time;

    if(event_count < sizeof(event_stamps) / sizeof(event_stamps[0]))
    {
        event_count++;
    }   
}

uint32_t events_get(void)
{
    time_t systime_s = SomeCallToGetTheCurrentTimeInSeconds();

    /* Remove elements in the array that are occurred greater than 30 minutes ago */
    int i;
    for(i = event_count; --i >= 0; )
    {
        /* Events arrive in order so events further away in time occur at higher array
         * indices. Therefore, once an event is reached that is sooner than the cutoff
         * time (30 minutes * 60 seconds), there are no more events to remove */
        if(systime_s - event_stamps[i] <= (30 * 60))
        {
            break;
        }

        event_count--;
    }

    return event_count;
}

毋庸置疑,这个阵列非常大(60 * 30 = 1800个元素* 4 = 7200 B)并且不适合我的小型处理器。有没有办法可以在不占用太多数据空间的情况下跟踪这些事件?

2 个答案:

答案 0 :(得分:1)

使用以秒为单位的循环位数组:1800位,持续30秒。

记录上次活动时间。

设置相应的位并记录事件发生的时间,但首先清除上一个事件时间和现在之间的所有位。

报告事件数时,首先清除上一个事件时间和现在之间的所有位,然后计算这些位。

答案 1 :(得分:1)

如果您只需要保留最近30分钟(1800秒)的历史记录,并且每秒只能有一个事件,那么每个事件只需要一个位,因此请使用位字段。每个位的索引表示从当前时间开始的以秒为单位的偏移量。

每秒循环重复:
整个场向右移一位。表示1800秒前事件的最后一位从阵列中删除。如果是1,则递减事件计数器。检查事件是否在第二次发生,如果发生,则将索引0处的位设置为1,并递增事件计数器。 (而不是移动整个数组,可以使用另一个索引变量来表示0的时间偏移量。)

如果事件很少或非事件很少,可以使用run-length encoding实现额外的内存改进。