【发布时间】:2023-03-19 08:00:02
【问题描述】:
假设您对一堆独立的时变值感兴趣,每个值都代表某物的当前状态。这些值不会按任何固定时间表更改,并且无法从旧值预测新值。举一个具体的例子,假设您有一堆股票,并且您有兴趣跟踪它们的价值,并且每当对该股票进行交易时,您都会获得有关单个股票的更新。 (我的实际问题与股票无关,但希望它们能让我的理解更容易理解。)
除了只知道每只股票的当前价格之外,您还希望能够选择过去的任意时间点并获得一个“快照”,告诉您每只股票的最新交易价格是多少当时。因此,例如,您应该能够说“截至上周二下午 4:53,我跟踪的每只股票的最新价值是多少?”并有效地得到准确的答案。
我可以想到三种方法来做到这一点,但我对其中任何一种都不太满意。
1.保留日记。 按时间顺序保留所有交易的清单。更新只是添加到列表中,查询是从时间戳等于或早于指定时间戳的第一个条目开始的线性向后扫描。这将使更新成为一个恒定时间操作,但您可能必须扫描整个日志以找到所有交易的值,因此更新为 O(1),快照为 O(u),其中 u 是更新的总数。由于显而易见的原因,所需的内存是 O(u)。
2。编写检查点。 像以前一样维护一个日志,但不是每个条目都只包含新股票价格,而是更新包含 每个 股票的当前价格(截至该更新)。这计算起来很便宜:由于上次更新也包含所有这些信息,您只需将其全部复制,除了价格实际发生变化的一只股票。现在可以使用 O(log u) 操作来完成快照(在日志上使用二进制搜索来定位在指定时间戳之前或之上的最后一个条目)。然而,更新变为 O(s),其中 s 是系统中的股票数量,而且所需的总内存从第一个策略中的 O(u) 变为 O(s*u) ——如果这两个都是问题s 和 u 都很大。
3。分开的期刊。 为每只股票维护一个单独的日志,并将每只股票的更新写入其自己的日志,再次按时间顺序。要快照,请检查每个期刊并使用二进制搜索来找到正确的更新。它需要 O(u) 内存,更新是 O(1) 操作,快照可以在 O(s * log u) 时间内完成。这是三种方法中我最喜欢的方法,但我觉得它可能会有所改进,因为它忽略了不同股票更新时间之间的任何关系。
我错过了更好的方法吗?这是一个已经研究过并有普遍接受的解决方案的问题吗?
【问题讨论】:
-
查看 VCS(如 Mercurial)如何处理文件:它们通常被认为可以在空间和速度要求之间提供良好的折衷。
标签: algorithm