【问题标题】:Data structure for "limited memory map"“有限内存映射”的数据结构
【发布时间】:2016-04-07 11:53:39
【问题描述】:

我想实现一个关联集合,将键 K 映射到值 V。我还想将每个值 V 与权重相关联,所以我们有 Map[K → (V, Double)]。

现在的想法是拥有这个集合的有限内存版本,它只存储超过权重阈值 t 的元素。每次将元素 e 插入此集合中,我们都会将 e 的权重增加一些量,例如1,并将所有其他元素的权重 e' != e 衰减某个衰减因子,例如 0.0001。 这确保了此集合中存在的元素要么是 a. 最近,或 b。 经常

当然,人们可以实现这种数据结构的简单版本,它主动执行衰减操作,并检查所有元素的阈值 t 的偏差。那将是非常低效的。

我想知道是否已经有一个数据结构可以做到这一点。也许有一个相关的数据结构可以用来实现我的要求。感谢您的意见。

【问题讨论】:

标签: memory data-structures hashmap


【解决方案1】:

这听起来像是 LFU(最不常用)缓存驱逐策略的一种变体,其中驱逐的决定会根据更新的相对比例考虑一个额外的阈值。

您不一定需要在插入时主动衰减所有其他条目 - 只需保留所有元素中的插入总数,以便您可以通过评估它是否超过该点的阈值来计算是否保留特定的驱逐候选者。

一种稍微不同的方法,不使用权重,将键按时间存储在桶中,其中键值查找是在特定桶的上下文中完成的。

  • 每个存储桶都有一个关联的时间范围,在该时间范围内可以将值插入到存储桶中。
  • 每个存储桶内部都有一个K -> V 映射。
  • 将保留K -> Bucket 的附加映射。
  • 桶将被插入到有序列表中。

插入数据结构会:

  • 如果现在超出最近存储桶的有效时间范围,则分配一个新的当前存储桶。
  • 检查桶中是否已经存在K
  • 如果没有,则将K -> V 插入到当前存储桶中,并将K -> current 插入到存储桶映射的键中。
  • 如果它存在于当前(最近的)存储桶中,则什么也不做。
  • 如果它存在于旧存储桶中,请将其移动到当前存储桶并更新存储桶映射。

最近使用的东西会移到最近的存储桶中。不属于旧桶的东西。您会定期清除旧存储桶。

缺点是使用时间来衰减,尽管您可能会在存储桶级别使用上述方法,因此由于存储桶数量少于集合中的项目数量,因此将成本降低到可接受的水平.

【讨论】:

  • 这是一个很好的观察。但是,LFU 不考虑新近度。缓存驱逐的唯一标准是绝对访问数。在我的模型中,一个已被访问 1000 次但返回一百万次插入的条目将在一个仅被访问 10 次的项目之前被驱逐。请注意,我没有在这里实现缓存 - 我实际上需要数据结构来平衡频率与新近度(可通过衰减因子进行调整)。
  • 模拟两种行为(LFU 和您上面描述的天真实现)并查看行为变化的程度会很有趣。大声思考,更新频率较低的内容可能平均更新频率较低,除非单个密钥在集群中更新多次,然后不会持续很长时间,因此根据您的预期,它可能是一个足够好的近似值使用和更新模式。
  • 然后,你的评论更新和我想的一样:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-08
  • 2012-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多