保证唯一代理键分配 - 非二分图的最大匹配

时间:2009-02-22 01:18:00

标签: algorithm graph-theory surrogate-key

我正在维护一个数据仓库,其中包含有关必须合并的一类实体的多个数据源。每个源都有一个自然键,应该发生的是每次为每个自然键创建一个且只有一个代理键。如果来自具有特定自然键的一个源系统的一条记录与来自具有不同自然键的另一源系统的另一条记录表示相同的实体,则将为两者分配相同的代理键。

换句话说,如果源系统A具有表示与源系统B的自然密钥DEF相同的实体的自然密钥ABC,我们将为两者分配相同的代理密钥。该表如下所示:

SURROGATE_KEY   SOURCE_A_NATURAL_KEY    SOURCE_B_NATURAL_KEY
 1               ABC                     DEF

那就是计划。然而,这个系统已经生产了一段时间,而代理键的分配是一团糟。在源系统B知道它之前,源系统A将在一天给出自然键ABC。 DW为其分配了代理键1。然后源系统B开始给出自然键DEF,它表示与源系统A的自然键ABC相同的东西。 DW错误地给出了这个组合代理键2.表格如下所示:

SURROGATE_KEY   SOURCE_A_NATURAL_KEY    SOURCE_B_NATURAL_KEY
 1               ABC                     NULL
 2               ABC                     DEF

所以仓库很乱。有比这更复杂的情况。我有一个简短的清理时间表,需要为自然键映射找出一套干净的代理键。

一个小小的谷歌搜索显示,这可以被建模为非二分图中的匹配问题:

Wikipedia - Matching

MIT 18.433 Combinatorial Optimization - Lecture Notes on Non-Bipartite Matching

我需要一个易于理解的Edmond路径,树和花算法的实现(不是最佳表现)。我没有正式的数学或CS背景,我所拥有的是自学成才,今晚我不在数学顶级空间。有人可以帮忙吗?我将非常感谢能够指导我实施的精心编写的解释。

编辑:

数学方法是最佳的,因为我们希望最大化全球适应度。一种贪婪的方法(首先采用A的所有实例,然后是B,然后是C ......)将你描绘成一个局部最大角落。

无论如何,我把这个推回给业务分析师手动完成(全部2000万)。我正在帮助他们评估全球匹配质量的功能。这是理想的,因为无论如何他们都是签约的,所以我的背后都有。

不使用代理键不会改变匹配问题。仍然需要发现和维护1:1自然键映射。代理键是一个方便的锚点,仅此而已。

3 个答案:

答案 0 :(得分:2)

我得到的印象是你的错误方式;正如cdonner所说,还有其他方法可以重建关键结构,而不必经历这个混乱。特别是,您需要保证给定记录的自然键始终唯一(违反此条件会让您陷入混乱!)。让ABCDEF同时识别相同的记录是灾难性的,但最终可以修复。我甚至不确定你为什么需要代理钥匙;虽然他们确实有许多优点,但我会考虑采用纯粹的关系,只是从你的架构中掏出它们,一个Celko;它可能只是让你摆脱这个烂摊子。但这是在查看整个架构后必须做出的决定。

为了解决您的潜在解决方案,我已经提取了我的DB West的图论理论第二版的副本,该版本描述了第144页的开花算法。您需要一些数学背景使用数学符号和图论来遵循算法,但它足够简洁,我认为它可以帮助(如果你决定走这条路线)。如果您需要解释,请首先查阅关于图论的资源(维基百科,您的本地图书馆,Google,无论在哪里),或者询问您是否找不到所需内容。

  

<强> 3.3.17。算法。(Edmonds'Blowom Algorithm [1965a] --- sketch)。

     

输入。图表GM中匹配的GM - 非饱和顶点u。< / p>      

想法。探索M - 来自u的交替路径,为每个顶点记录到达它的顶点,并在找到时收缩开花。维护集合ST类似于算法3.2.1中的集合,Su组成,并且沿着饱和边缘到达顶点。到达不饱和顶点会产生增强。

     

初始化。 S = {u}T = {}(空集)。

     

迭代。如果S没有未标记的顶点,请停止;没有M - 来自u的扩充路径。否则,请在v中选择未标记的S。要从v进行探索,请先在y中考虑每个N(v)y不在T

     

如果ym限制为y,则从M追溯(根据需要展开花朵)以报告(u, y) - 增加y - 路径

     

如果S位于v,那么就会找到一朵花。暂停S的探索并收缩花朵,将TS中的顶点替换为y中的一个新顶点。在较小的图表中继续从此顶点搜索。

     

否则,wM的某些y匹配。在T(从v到达)中加入w,并在S中加入y(从v到达)。

     

在探索v的所有此类邻居后,标记{{1}}并迭代。

此处描述的算法在时间O(n ^ 4)中运行,其中n是顶点数。 West提供对运行速度与O(n ^ 5/2)或O(n ^ 1/2 m)一样快的版本的引用(m是边数)。如果你想要这些引用,或引用Edmonds的原始论文,只要问一下,我会把它们从索引中挖掘出来(这本书中哪种方式很糟糕)。

答案 1 :(得分:1)

我认为通过建立一组规则并使用一组以迭代方式强制执行每条规则的简单查询来攻击您的键映射表会更好。也许我过于简单化了,因为你的例子很简单。

以下是规则的示例 - 只有您可以决定适用哪些规则:

  • 如果有重复项,请使用最低(最早)的代理键
  • 使用具有最高(最新)代理键
  • 的行中的自然键
  • 使用最完整的映射行中的自然键
  • 使用每个自然键的最新出现次数
  • ......?

一旦建立了规则,编写重建密钥映射的查询就很简单了。我不确定这可能是一个数学问题?

答案 2 :(得分:0)

如果您正在寻找实现,Eppsteins PADS库有一个匹配的算法,这应该足够快,您的目的,一般匹配算法在CardinalityMatching.py。实施中的评论解释了正在发生的事情。该库易于使用,用Python提供图形,您可以使用字典G表示图形,这样G [v]给出了顶点v的邻居列表(或集合)。

示例:

G = {1: [1], 2:[1,3], 3: [2,4], 4:[3]}

给出一个包含4个顶点的折线图。