为具有可变元素的优先级队列确定最佳 ADT (C++)
Posted
技术标签:
【中文标题】为具有可变元素的优先级队列确定最佳 ADT (C++)【英文标题】:Determining the best ADT for a priority queue with changeable elements (C++) 【发布时间】:2012-12-07 04:19:33 【问题描述】:第一次在这里发帖,我是初学者 - 希望我能让自己变得有用...
我正在努力寻找并理解完成我所追求的工作的 ADT/概念。我猜它已经在那里了。
我有一个对象数组/列表/树(待决定的容器),每个对象都有一个计数,该计数与在进程的迭代中没有使用的次数相关。随着迭代的进行,每个对象的计数累加 1。我的想法是迟早我将需要任何未使用的对象正在使用的内存,因此我将删除它们以为不在 RAM 中的对象腾出空间(其中将有一个初始计数“0”) - 但是,如果事实证明我使用的对象仍在内存中,它的计数将重置为“0”,我拍拍自己的背部,因为不必访问其内容的磁盘。
缓存?
主流程循环将包含类似于以下内容的内容:
if (object needs to be added && (totalNumberOfObjects > someConstant))
object with highest count deleted from RAM and the (heap??)
newObject added with a count of '0'
if (an object already in RAM is accessed by the process)
accessedObject count is set to '0'
for (All objects in RAM)
count++
我可以大吵大闹(很长一段时间)并自己搞砸,但我认为从 word go 中学习最有效的方法会很有趣。
类似堆的东西?
【问题讨论】:
所以你的数据结构应该针对搜索进行优化? 可能,我试图找到一种方法,使数据结构既代表数据本质(四叉树和/或八叉树),又代表从 RAM 中删除。我开始认为也许我使用缓存方面使用的任何内容作为基本数据类型。如果它需要排序,那就这样吧。你指的是哈希表吗? (我不熟悉的另一件事) 【参考方案1】:您可以为此使用堆,但我认为这有点过头了。听起来你不会有很多不同的计数值,并且每个计数都会有很多对象。如果这是真的,那么您只需要将对象线程化到具有相同计数的对象列表中。这些列表本身排列在一个 dequeue 中(或 C++ 坚持称之为“deque”)。
这里的关键是你需要增加所有对象的计数,并且如果可能的话,你可能希望它是 O(1),而不是 O(N)。这是可能的:关键是每个列表的标题还包含其计数与下一个较小计数的差异。具有最小计数的列表的标题包含从 0 开始的增量,这是最小的计数。要增加所有对象的计数,您只需将这个数字增加一即可。
要将对象的计数设置为 0,请从其列表中删除该对象(这意味着您始终需要通过其列表迭代器来引用对象,或者您需要实现自己的侵入式链表),或者 (1)如果该列表的计数为 0,则将其添加到底部列表中,或者 (2) 创建一个计数为 0 的新底部列表,其中仅包含该对象。
创建新对象的过程是相同的,只是您不必从当前列表中取消链接。
要从内存中逐出一个对象,请选择顶部列表(即计数最多的列表)开头的对象。如果该列表为空,则将其从出队中弹出。如果需要更多内存,可以重复此操作。
所以所有操作,包括“增加所有计数”,都是 O(1)。不幸的是,存储开销是每个对象两个指针,加上每个唯一计数的两个指针和一个整数(在最坏的情况下,这与对象的数量相同,但在实践中可能要少得多)。由于很难想象任何其他算法使用少于一个指针加上每个对象的计数,这可能甚至不是时空权衡;额外的空间需求很小。
【讨论】:
我会支持你,但我还不能!您如何看待此处概述的方法:***.com/questions/2504178/lru-cache-design(我花了一些时间才找到它) 该方法是我算法的精简版;主要区别在于它不会让您知道对象的年龄(但也许您并不关心),而且它更精确。我已经在准备根据需求增加(或缩小)缓存的上下文中使用了我的算法,并且我想在对象太旧时自动删除它们,即使有空间保留它们。我更喜欢侵入式列表而不是哈希表,但口味(和要求)各不相同。 我不需要知道他们的绝对年龄,只知道相对年龄。最终能够增长和缩小缓存会很好,但我还没有阅读有关如何查询操作系统以获取内存信息的内容,或者确实让它“告诉”我的缓存它的大小。首先要解决更大的问题。 '侵入性列表'>> 好的,谷歌搜索! 唷,要学的东西很多……如果你在这里看到这篇文章 - 你会看到我是多么的初学者:***.com/questions/13784732/… 祝你好运!我不是一个java程序员,所以我怀疑我能帮上什么忙。 ***.com/questions/3361145/intrusive-lists 有一些关于侵入性列表的信息,以及一些包含更多信息的链接。我的缓存是连接缓存,不是内存缓存,如果短时间内创建了很多新连接,我会增加它们,然后让它们衰减;避免连接抖动。不过,这是一个稍微不同的问题域。以上是关于为具有可变元素的优先级队列确定最佳 ADT (C++)的主要内容,如果未能解决你的问题,请参考以下文章