有效地合并许多未排序的列表

时间:2015-12-31 09:40:03

标签: algorithm parallel-processing

我有很多未分类的List包含(user,amountspend)个元组。每个清单对应一天。 现在我想将所有列表合并为一个列表,其中包含给定用户的累计值。我有两种方法:

  • 方法1:对各个列表进行排序,然后迭代地使用合并排序。

  • 方法2:以用户为键形成HashMap,然后遍历列表 并更新key的值(如果存在)或添加带有值的新键。

如果有m列表且每个列表的长度可能不同(k1,k2,...,km)

问题:

哪种方法有效?
哪个解决方案可以在多个线程中运行? 或者有更好的解决方案吗?

示例:

第1天:(user1,100),(user2,200)
第2天:(user2,10),(user1,100),(user3,10)
合并后列出:(user1,200),(user2,210),(user3,10)

3 个答案:

答案 0 :(得分:1)

HashMap方法更好,因为它的O(N)。两种解决方案都可以在多个线程中运行,但需要不同的修改来支持并发。

答案 1 :(得分:1)

1整体方法和复杂性

我想:

  • 客户数量很大但有限= N
  • 天数持续增长= M
  • 也许每一天,我们都有每个客户(或几乎那个)。

完成工作的最小复杂性:

  • 处理每个数据,因此 M.N操作。因为你不想保留总和的元素,你只需要做: 部分和+新值,所以,一切都需要M.N x有限的时间(我想你没有数十亿的数十亿美元)

  • 你必须在N个客户端上聚合数据(对于每个数据,你必须在每个客户端上查找,求和,存储......)。 对我来说,最短时间是至少对客户端进行一次排序(或任何索引它们的方法), 所以,时间就是O(N log N),最好的算法和最好的算法 实现(存在更快的方式,但具有非常大的空间)。

因此,您至少需要O(N log N)+ O(M.N)。

2种可能的解决方案:

您的方法1浪费时间:因为您对每个列表进行排序(使用相同的数据)。 你需要M.O(N log N)+ O(M.N)。 您只需要一种(以便能够在之后求和)。

您的方法2是最短的方式。

3如何并行化?

您(至少)有两种方法来分割您的数据:天数或客户端。因为您想要对客户端求和,请使用 第二个。

您的流程易于扩展。

然后你可以使用一个简单的哈希函数(客户端的第一个或最后一个字符,或者非常简单的东西) =>每个线程(或进程或机器)接收每个数据,并仅为其客户端保留数据。

您可以像这样分割每个工作(流程,总和,检索......)。

如果整个时间几乎相同:

用k过程,你将得到k.O(N / k log N / k)+ k * Ox(M.N)+ k.O(M.N / k)

你通过分割N / k赢得的时间,你选择回报(牛,我想非常快)。

然后,您可以在多台计算机上分配作业,这些计算机将是独立的。

希望它有所帮助。

答案 2 :(得分:-1)

sort和merge解决方案的复杂性是O(mn log n)+ O(n log m),其中m是假设每个列表的大小为n的列表数。

为了计算基于散列的解决方案的复杂性,让我们假设有k个用户。将k个元素插入https://addons.mozilla.org/en-US/firefox/addon/httpfox/ (Java)或HashMap(C ++)的操作取O(k log k)。在最佳情况下改变mn-k值的值取(mn-k)O(1)并且在最坏的情况下取(mn-k)O(log k)。总体复杂度为O(mn log k)。因此,当k远小于mn时,Hashing似乎更好。[/ p>