9

我必须编写一个程序,将 10'000'000+ 个实体相互比较。实体基本上是数据库/csv 文件中的扁平行。

比较算法必须非常灵活,它基于最终用户输入规则的规则引擎,每个实体都与其他实体匹配。

我正在考虑如何将这项任务拆分为更小的工作量,但我还没有找到任何东西。由于规则是由最终用户输入的,因此对 DataSet 进行预排序似乎是不可能的。

我现在要做的是将整个 DataSet 放入内存并处理每个项目。但这效率不高,需要大约。20 GB 内存(压缩)。

您知道如何拆分工作负载或减小其大小吗?

谢谢

4

5 回答 5

13

如果您的规则处于最高抽象级别(例如任何未知的比较函数),您就无法实现您的目标。10^14 次比较操作将运行很长时间。

如果规则不完全通用,我会看到 3 种优化不同情况的解决方案:

  • 如果比较是可传递的并且你可以计算哈希(有人已经推荐过),那就去做吧。哈希也可能很复杂,不仅是您的规则 =)。找到好的散列函数,它在许多情况下可能会有所帮助。

  • 如果实体是可排序的,则对它们进行排序。为此,我建议不要就地排序,而是构建项目的索引(或 ID)数组。如果您的比较可以转换为 SQL(据我了解您的数据在数据库中),您可以在 DBMS 端更有效地执行此操作并读取排序索引(例如 3,1,2 这意味着 ID=3 的项目最低,ID=1 居中,ID=2 最大)。然后你只需要比较相邻的元素。

  • 如果事情值得,我会尝试使用一些启发式排序或散列。我的意思是我会创建不一定唯一标识相等元素的哈希,但可以将您的数据集分成组,在这些组之间肯定没有一对相等的元素。然后所有相等的对将在内部组中,您可以逐个读取组并在不是 10 000 000,而是例如 100 个元素的组中进行手动复杂函数计算。另一种子方法是启发式排序,目的相同,以确保相同的元素不在数据集的不同结尾。之后,您可以逐个读取元素并与之前的 1000 个元素进行比较(例如,已读取并保存在内存中)。例如,我会在内存中保留 1100 个元素,并在每次新的 100 个出现时释放最旧的 100 个。这将优化您的数据库读取。如果您的规则包含 (Attribute1=Value1) AND (...) 之类的规则,或 (Attribute1 < Value2) AND (...) 之类的规则或任何其他简单规则,则此方法的其他实现也是可能的。然后您可以先按此标准进行聚类,然后比较创建的聚类中的项目。

顺便说一句,如果您的规则认为所有 10 000 000 个元素都相等怎么办?您想获得 10^14 个结果对吗?这个案例证明在一般情况下你无法解决这个任务。尝试做一些限制和假设。

于 2013-02-28T12:40:08.120 回答
4

我会尝试考虑规则层次结构。例如,假设规则 A 是“颜色”,规则 B 是“形状”。

如果您首先按颜色划分对象,则无需将红色圆圈与蓝色三角形进行比较。

这将减少您需要进行的比较次数。

于 2013-02-28T12:22:29.213 回答
1

我会从每个实体创建一个哈希码。您可能必须从哈希生成中排除 id,然后测试是否相等。如果你有散列,你可以按字母顺序排列所有的散列码。将所有实体按顺序排列意味着很容易检查双精度数。

于 2013-02-28T12:10:12.620 回答
1

如果您想将每个实体与所有实体进行有效比较,那么您需要对数据进行聚类,比较完全不相关的事物的理由非常少(比较 Clothes 和 Human 没有意义),我认为您的规则会尝试对数据进行聚类.

所以你需要对数据进行聚类,尝试一些聚类算法,比如K-Means

另请参阅 Apache Mahout

于 2013-02-28T12:48:46.050 回答
-1

您是否正在为此寻找最合适的排序算法?我认为分而治之似乎不错。如果算法看起来不错,您可以有很多其他方法来进行计算。使用 MPICH 或其他东西的特别并行处理可能会给你一个最终目的地。

但在决定如何执行之前,您必须先考虑算法是否适合。

于 2013-02-28T12:12:56.790 回答