2013-02-28 56 views
8

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

比较算法是相当灵活的,它是基于在最终用户输入规则的规则引擎和各实体对每一个其他实体相匹配。

我在考虑如何将此任务分解为更小的工作负载,但我还没有找到任何东西。由于规则是由最终用户预先排序输入的,DataSet似乎是不可能的。

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

您知道我如何分割工作量或缩小尺寸吗?

感谢

+6

每个实体都与*每*其他实体进行比较?你确定?这是〜5x10^13个组合......如果你能每秒执行一百万次比较,那将需要超过一年半的时间。 – 2013-02-28 12:09:57

+0

此规则引擎是否已经写入?这似乎是比C#更适合于数据库的工作。 – 2013-02-28 12:13:50

+0

非常多。如果我知道这些规则如何与现在的比较,我可以大大减少工作量。但我不知道他们究竟如何定义匹配规则 – senic 2013-02-28 12:13:55

回答

12

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

如果规则不完全总的来说,我看到3个解决方案,优化不同的情况:

  • 如果比较传递的,你可以计算哈希(有人已经建议本),做到这一点。哈希值也可能很复杂,不仅仅是你的规则=)。找到很好的散列函数,它可能在很多情况下都有帮助。

  • 如果实体可排序,对它们进行排序。为此,我建议不要在原地排序,而是建立一个项目的索引(或ID)数组。如果您的比较可以转换为SQL(因为我的理解您的数据在数据库中),您可以更有效地在DBMS端执行此操作并读取已排序的索引(例如3,1,2表示ID = 3的项是最低的,ID = 1在中间,ID = 2是最大的)。那么你只需要比较相邻的元素。

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

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

1

我会创建从每个实体的哈希码。您可能必须从散列生成中排除该id,然后测试equals。如果你有散列,你可以按字母顺序排列所有的散列码。让所有实体排列顺序意味着检查双打非常容易。

+0

当然,但RuleSet可以包含复杂的规则。你不能只比较行。 (例如,您想对字符串进行标准化,计算字符串距离等) – senic 2013-02-28 12:12:33

-1

您是否正在寻找最适合这种分类算法的种类? 我认为Divide和Concur似乎很好。 如果算法看起来不错,您可以有很多其他方法来进行计算。使用MPICH进行特殊的并行处理可能会给你一个最终目的地。

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

4

我会尝试考虑规则层次结构。 比方说,规则A是“颜色”,规则B是“形状”。

如果你的颜色首先鸿沟对象, 比没有需要比较红圈蓝三角。

这会减少你需要做的比较次数。

1

如果你想每一个实体与您需要将数据集聚所有实体不是有效地比较,有非常少的原因比较完全无关的事情(比较人类衣服就没有意义了),我想你的规则会尝试对数据进行聚类。

,所以你需要将数据集聚,尝试像K-Means一些聚类算法。

而且看,Apache Mahout