Algorithm 如何确定事件的速率(移动平均)是否超过阈值

Algorithm 如何确定事件的速率(移动平均)是否超过阈值,algorithm,mainframe,moving-average,smoothing,rexx,Algorithm,Mainframe,Moving Average,Smoothing,Rexx,编辑添加的信息 最初,这只是一个通用算法和语言/平台不可知论。然而,我将自己回答这个问题,答案实际上是特定于所使用的工具的 这是为了在z/OS下的IBM大型机上使用运行REXX脚本的Ops/MVS自动化工具进行事件检测 因此,发布的答案可能适用于Python、Perl、bash、Java等语言;只是在这种特殊情况下使用的产品有一个特定的功能来实现这一点 添加信息结束 我的问题与此非常相似: 这将是一个答案: 这可以通过移动平均线来实现。以你最后的N个事件为例 其中N是平均窗口的大小。计算时间

编辑添加的信息

最初,这只是一个通用算法和语言/平台不可知论。然而,我将自己回答这个问题,答案实际上是特定于所使用的工具的

这是为了在z/OS下的IBM大型机上使用运行REXX脚本的Ops/MVS自动化工具进行事件检测

因此,发布的答案可能适用于Python、Perl、bash、Java等语言;只是在这种特殊情况下使用的产品有一个特定的功能来实现这一点

添加信息结束

我的问题与此非常相似:

这将是一个答案:

这可以通过移动平均线来实现。以你最后的N个事件为例 其中N是平均窗口的大小。计算时间 这N个事件中第一个和最后一个事件之间的差异。如果你 以秒为单位进行测量,并希望以每分钟事件的速率进行测量 然后将60秒除以以单位表示的时间差 秒,然后乘以N-1

除非我想避免存储以前事件的信息。我也只对移动平均线超过阈值感兴趣,所以我对保持利率趋势不感兴趣

例如,我想知道我每分钟是否有超过3个事件。这是我的第一个方法:

  • 当第一个事件出现时,我创建一个计数1并记录 开始时间
  • 当另一个事件出现时,我增加计数并计算 从计数和经过的时间中选择速率
  • 如果速率超过允许值,则生成警报
  • 我意识到这是行不通的,因为如果你一周前有一个活动,然后在最后一分钟才有10个活动,那么平均“速率”是一周11个,即3.6/天,而不是当前的10/分钟速率

    因此,我想尝试以下方法:

  • 当第一个事件出现时,我创建一个计数1并记录 开始时间
  • 当另一个事件发生时,如果自上一个事件以来的时间超过了我想要测量速率的时间间隔(在我的示例中为1分钟),我将有效地放弃上一个事件,并记录计数1和当前时间作为新的开始时间(因为如果距离上次事件已经超过1分钟,则速率不能超过x/min,对吗?)
  • 如果自上次事件以来的时间未超过监控时间 间隔,递增计数并根据计数计算速率 以及经过的时间
  • 如果速率超过允许值,则生成警报

  • 这似乎很简单,但其他帖子(特别是这个问题:这是公认的答案:)似乎暗示了它比我想象的要多得多。

    使用以下伪代码:

    boolean update(long timestamp, History h, int windowSize, int minEventsToTrigger) {
        h.removeOlderThan(timestamp - windowSize);
        h.addEvent(timestamp);
        return h.size() >= minEventsToTrigger;
    }
    
    其中
    h
    是一种存储时间戳的方法,具有以下操作:

    • removelder than(t)
      :删除在
      t
      之前发生的所有事件。此操作将分期偿还
      O(1)
      ,因为每个事件将只删除一次,并且事件(最早的事件除外)将不会被查询多次以进行删除

    • addEvent(t)
      :在缓冲区末尾添加事件,或者如果缓冲区已满,则先删除最早的事件,然后添加新事件。操作
      O(1)
      ;将旧事件丢弃为新事件可以保证突发事件不会淹没系统、需要额外内存或破坏此代码——只要
      minEventsToTrigger
      小于
      h
      的容量,结果总是正确的

    我相信,这个伪代码在时间上是最优的,在空间上也可能是最优的。重要的是,它不需要任何类型的动态分配

    如果给定新事件,在
    windowSize
    时间单位内至少收到
    minEventsToTrigger
    ,则
    update
    函数返回true,否则返回false。请注意,该函数仅在收到每个事件时调用,因此只能准确地调用(在下一个事件之前不会检测到下降边缘)。如果您希望对此进行补救,您有两个选项:

    • 定期轮询以查看在调用
      h.removeOlderThan(timestamp-windowSize);
      后,条件
      return h.size()>=minEventsToTrigger;
      是否不再为真。如果事件非常罕见,这可能会造成浪费;如果仅在触发警报时执行此操作,则可能会节省大量不必要的操作
    • 使用某种计时器机制,一旦触发警报,在最早的事件到期后立即唤醒。这将保证事件到期和检查
      h.size()>=minEventsToTrigger
      之间的最小延迟

    Ops/MVS通过“OPSTHRSH”功能内置此功能:

    对于此特定场景,我们可以按如下方式调用它:

    if OPSTHRSH('A',60) > 3 then do something...
    

    OPSTHRESH('A',60)将返回当前事件为当前地址空间(任务)触发多少次的计数在60秒内。如果此值超过我的触发级别,则采取行动。在收到第一个事件60秒后,事件计数将重置。

    这是否回答了您的问题?如果不是,您可能需要澄清“移动平均”的含义(任何类型的平均都会导致您的示例不会触发阈值10)。@Dukeling它可能会触发,但我使用的语言除外(IBM大型机z/OS上的Ops/MVS REXX)不支持数组。自从询问之后,我发现Ops/MVS有一个内置函数来执行此任务。我不知道是否应该扩展我的答案以包含这些详细信息,然后再回答。或者干脆删除这个问题。我想你需要澄清一下,这是在较早时使用Ops/MVS;在这种情况下,我会保留这个问题,因为它是specific,另一方未回答