如何平衡BK树?是否必要?

8
我正在研究使用编辑距离算法在姓名数据库中实现模糊搜索。
我找到一种数据结构,据说可以通过分治方法加速 - Burkhard-Keller Trees。问题是我找不到关于这种特定类型的树的很多信息。
如果我用任意节点填充BK树,那么我出现平衡问题的可能性有多大?
如果BK树可能或很可能出现平衡问题,是否有办法在构建后平衡这样的树?
正确平衡BK树的算法是什么样子的?
我的思路如下:
似乎子节点在距离上是不同的,因此我不能简单地旋转树中给定的节点,而不重新校准其下面的整个树。但是,如果我能找到一个最佳的新根节点,这可能正是我应该做的。但我不确定如何找到最佳的新根节点。

我还将尝试一些方法,看看是否可以通过从空树开始插入预分配的数据来获得一个相对平衡的树。

  • 首先按字母顺序排序,然后从中间开始排队。(我不确定这是否是一个好主意,因为字母顺序并不等同于按编辑距离排序)。
  • 完全随机的数据。(这在很大程度上依赖于运气,以便偶然选择一个“不那么糟糕”的根节点。它可能会失败得很惨,而且可能具有概率保证是次优的)。
  • 从列表中的任意单词开始,按其与其他项目的编辑距离排序。然后从中间排队。(我觉得这将非常昂贵,并且仍然表现不佳,因为它不会计算所有单词之间的度量空间连接性 - 只会计算每个单词和单个参考单词之间的距离)。
  • 使用任何方法构建初始树,展开它(基本上像前序遍历一样),然后从中间排队获取新树。(这也将非常昂贵,我认为它可能仍然表现不佳,因为它不会提前计算所有单词之间的度量空间连接性,而只会获得不同但仍然不均匀的分布)。
  • 按名称频率排序,先插入最流行的,放弃平衡树的概念。(这可能是最合理的选择,因为我的数据不均匀分布,我不会有纯随机单词进来)。

我目前不担心名称同义词问题(比如Bill和William)。我会单独处理这个问题,而且我认为需要采用完全不同的策略。


1
你可能找到了你的问题的答案吗? - Egregore
我认为按名称频率排序(先插入最流行的)会是最快的。然而,在我的尝试中,我测量出反向频率(将最流行的插入到最后)优于我所有的尝试。我无法理解为什么,我原本期望相反的结果。 - Koray
1个回答

0
文章中有一个Lisp的例子:http://cliki.net/bk-tree。关于平衡树,我认为数据结构和方法似乎已经足够复杂了,并且作者并没有提到不平衡的树。当你遇到不平衡的树时,也许它并不适合你?


1
谢谢提供链接,但我并没有在构建BK树的基本算法方面遇到问题。Lisp示例是如何使用他们的库,并没有涉及树的平衡问题。“当你遇到不平衡的树时,也许它不适合你?”-您能详细说明一下吗?我还有哪些其他选择?例如,是否有某个特定的Vantage Point Tree衍生版本可以代替使用? - Merlyn Morgan-Graham
我不确定BK树是否好用。例如,字典树或卡特树也可以解决您的问题。当然,在二维欧几里得空间中,您可以采用快捷方式。请了解三角形不等式。 - Micromega
1
Tries(基数树)对于自动完成非常有用(这不是我要实现的),但对于拼写错误则没有那么有用。我想它们可以被修改以帮助加速Levinshtein计算,但它们不会给我一个基于编辑距离/度量空间的模糊匹配集合。“当然,在二维欧几里得空间中,你可以有快捷方式” - 这就是BK树的作用...它们只是度量空间树。 - Merlyn Morgan-Graham
可以,但是你可以实现通配符搜索:http://phpir.com/tries-and-wildcards/. - Micromega

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接