- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我需要限制在 deltaT 时间段内允许的事件数 n。我能想到的任何方法,空间都是 O(m),其中 m 是每个 deltaT 发送的事件请求的最大数量,或者 O(deltaT/r),其中 r 是可接受的分辨率。
编辑:deltaT 是一个相对于时间戳的滑动时间窗口。
例如:保留事件时间戳的循环缓冲区。在事件中裁剪所有早于 t-deltaT 的时间戳。如果时间戳的数量超过 n,则拒绝事件。将时间戳添加到缓冲区。
或者,初始化一个大小为 deltaT/r 的整数循环桶缓冲区,该缓冲区按相对于当前分辨率 r 的时间进行索引。维护指针i。在事件中,自上次事件以来的时间除以 r 后递增 i。将原始 i 和新缓冲区之间的缓冲区清零。在 i 处递增。如果 bugger 的总和超过 n,则拒绝。
什么是更好的方法?
我刚刚在 c# 中实现了我上面的第二个建议,固定 deltaT 为 1 秒,固定分辨率为 10 毫秒。
public class EventCap
{
private const int RES = 10; //resolution in ms
private int _max;
private readonly int[] _tsBuffer;
private int p = 0;
private DateTime? _lastEventTime;
private int _length = 1000 / RES;
public EventCap(int max)
{
_max = max;
_tsBuffer = new int[_length];
}
public EventCap()
{
}
public bool Request(DateTime timeStamp)
{
if (_max <= 0)
return true;
if (!_lastEventTime.HasValue)
{
_lastEventTime = timeStamp;
_tsBuffer[0] = 1;
return true;
}
//A
//Mutually redundant with B
if (timeStamp - _lastEventTime >= TimeSpan.FromSeconds(1))
{
_lastEventTime = timeStamp;
Array.Clear(_tsBuffer, 0, _length);
_tsBuffer[0] = 1;
p = 0;
return true;
}
var newP = (timeStamp - _lastEventTime.Value).Milliseconds / RES + p;
if (newP < _length)
Array.Clear(_tsBuffer, p + 1, newP - p);
else if (newP > p + _length)
{
//B
//Mutually redundant with A
Array.Clear(_tsBuffer, 0, _length);
}
else
{
Array.Clear(_tsBuffer, p + 1, _length - p - 1);
Array.Clear(_tsBuffer, 0, newP % _length);
}
p = newP % _length;
_tsBuffer[p]++;
_lastEventTime = timeStamp;
var sum = _tsBuffer.Sum();
return sum <= 10;
}
}
最佳答案
如果有这些变量呢:num_events_allowed、time_before、time_now、time_passed
在初始时间你会做:time_before = system.timer(), num_events_allowed = n
收到事件后,您执行以下操作:
time_now = system.timer()
time_passed = time_now - time_before
time_before = time_now
num_events_allowed += time_passed * (n / deltaT);
if num_events_allowed > n
num_events_allowed = n
if num_events_allowed >= 1
let event through, num_events_allowed -= 1
else
ignore event
这个算法的好处是 num_events_allowed 实际上是根据自上次事件以来耗时和可以接收的事件的速率递增的,这样你就可以增加每个事件可以发送的事件数time_passed 以保持在 n 的限制内。因此,如果您过早收到一个事件,您会将其递增小于 1,如果它在太长时间后递增,您将递增超过 1。当然,如果事件通过,你就会将津贴减 1,因为你刚刚得到一个事件。如果津贴超过了最大事件 n ,则将其返回到 n ,因为在任何时间阶段都不能允许超过 n 。如果允许量小于 1,则不能发送整个事件,不要让它通过!
关于algorithm - 限制每个时间段的事件数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12530252/
如果我使用以下方法计算 java.time 中 2 个 LocalDate 之间的差异: Period p = Period.between(testDate, today); 然后我得到一个包含年、
我正在开发一个有多种不同费率的预订平台。这些费率由一天中的时间、星期几和一年中的一天决定。以下是所涉及的间隔类型的一些示例: 周一至周五,上午 9 点至下午 5 点 周六和周日,中午 12 点到早上
我有大量数据,包括开始时间、停止时间和值。开始和停止时间因行而异,以 5 分钟为增量。我正在尝试创建一个新的数据框,该数据框具有 5 分钟的间隔以及该间隔在行的开始和停止范围内的所有行的总和。 我有一
我有一个这样的表: --------------------------------------------- |Id | Step | StartedAt
我有一个网络应用程序,用户将在其中输入 2 个日期。一个 StartDate 和一个 EndDate。现在我想编写它,以便在选择 StartDate 和 EndDate 时确定有多少周,然后显示这些周
这看起来并不直截了当。 我正在尝试: @Override public int compare(Period o1, Period o2) { return o1.toStandardDays
我必须为团队发送 session 邀请,这是我的邮件 $ical = 'BEGIN:VCALENDAR PRODID:-//Microsoft Corporation//Outlook 11.0
我有这个 ISO 8601 时间段字符串: P0Y0M0DT3H5M0.000S 并且 PHP7.4 无法用它构造 DateInterval。 format('%h Hours %m Minutes
我想要获取包含一段时间(格式为 HH:MM:SS)的多个单元格的总和。在 LibreOffice Calc 4.0.3.3 中,我复制粘贴了 G14:G21 范围内的时间段,并将单元格格式设置为时间
我有一个表(MySQL),每n秒捕获一次样本。该表有很多列,但重要的是两列:时间戳(TIMESTAMP 类型)和计数(INT 类型)。 我想做的是获取一定时间范围内计数列的总和和平均值。例如,我每 2
我有一个表(MySQL),每n秒捕获一次样本。该表有很多列,但重要的是两列:时间戳(TIMESTAMP 类型)和计数(INT 类型)。 我想做的是获取一定时间范围内计数列的总和和平均值。例如,我每 2
我在一个项目上使用 joda-time (1.6.2),我正在做的其中一件事就是计算预测时间和实际时间之间的差异。这种差异有时是积极的,有时是消极的。虽然适当的方法可能是使用 Duration 而不是
我有一个表 (MySQL),它每 n 秒捕获一次样本。该表有很多列,但最重要的是两列:一个时间戳(TIMESTAMP 类型)和一个计数(INT 类型)。 我想做的是获取计数列在一段时间内的总和和平均值
我想让我的折线图显示过去 3 个月的数据。 GDS 有一个“最后一个季度”的日期范围,但这显示的是 Q1、Q2、Q3 或 Q4。我需要的是过去3个整月(不算当月)的数据。我尝试创建一个计算字段,但事实
我想让我的折线图显示过去 3 个月的数据。 GDS 有一个“最后一个季度”的日期范围,但这显示的是 Q1、Q2、Q3 或 Q4。我需要的是过去3个整月(不算当月)的数据。我尝试创建一个计算字段,但事实
我是一名优秀的程序员,十分优秀!