Algorithm top-k选择/合并
我有n个排序列表(5Algorithm top-k选择/合并,algorithm,database-design,Algorithm,Database Design,我有n个排序列表(5
top2 (L1: [ 'a': 10, 'b': 4, 'c':3 ]) = ['a':10 'b':4]
top2 (L2: [ 'c': 5, 'b': 2, 'a':0 ]) = ['c':5 'b':2]
更有趣的是,当我想要所有排序列表中的前k名组合时
top2(L1+L2) = ['a':10, 'c':8]
仅将单个列表中的前k项组合在一起不一定会得到正确的结果:
top2(top2(L1)+top2(L2)) = ['a':10, 'b':6]
目标是减少所需的空间,并保持已排序的列表较小
top2(topX(L1)+topX(L2)) = ['a':10, 'c':8]
问题是,是否有一种算法来计算组合的top k,该k具有正确的顺序,同时在某个位置切断列表的长尾。如果有:如何找到极限X,在哪里可以安全地切割
注意:正确的计数并不重要。只有命令是正确的
top2(magic([L1,L2])) = ['a', 'c']
如果我对你的问题理解正确,正确的输出是前10项,而不管每个项来自哪个列表。如果这是正确的,那么从每个列表中的前10个项目开始将允许您生成正确的输出(如果您只希望在输出中有唯一的项目,但输入可能包含重复项,那么您需要在每个列表中有10个唯一的项目) 在最极端的情况下,所有顶部项目都来自一个列表,而忽略其他列表中的所有项目。在这种情况下,一个列表中有10个项目就足以产生正确的结果
您没有指定有多少个列表。如果n很小,那么步骤4可以非常简单地完成(只需重新排序列表)。随着n的增长,您可能需要考虑更有效的方法来使用几乎已排序的列表。总的来说,我认为您遇到了麻烦。想象一下下面的列表:
['a':100, 'b':99, ...]
['c':90, 'd':89, ..., 'b':2]
你有k=1(也就是说,你只想要最上面的一个)“b”是正确的答案,但你需要一直往下看第二个列表的末尾,才能意识到“b”胜过“a”
编辑:
如果你有正确的分布(长的、低计数的尾巴),你可能会做得更好。让我们暂时保持k=1,让我们的生活更轻松
基本算法是保存一个到目前为止看到的密钥及其相关总数的哈希图。浏览列表,处理元素并更新地图
关键的观察结果是,一个键最多可以通过每个列表当前处理点的计数总和(称为总和S)获得计数。因此,在每一步中,您都可以从哈希映射中删除总数比当前最大计数元素少S以上的任何键。(我不确定需要删减什么样的数据结构,因为需要查找给定计数范围的键—可能是优先级队列?)
当哈希映射中只有一个元素,且其计数至少为S时,可以停止处理列表并返回该元素作为答案。如果您的计数分布很好,那么这个提前退出实际上可能会触发,这样您就不必处理所有的列表。我不知道两个列表中是否出现“a”,它们的计数必须合并。下面是一个新的内存高效算法: (新)算法:
注意:此算法假定可以快速比较ID。字符串比较并不简单。我建议将字符串ID散列为整数。它们不必是唯一的散列,但必须检查冲突,以便正确排序/比较所有ID。当然,这会增加内存/时间复杂性。此算法使用O(U)内存,其中U是唯一键的数量。我怀疑能否达到较低的内存界限,因为在所有键相加之前,无法判断哪些键可以丢弃
完美的解决方案要求所有元组至少检查一次 然而,不需要检验就可以接近完美的解决方案