硬排序问题 - 我应该使用啥类型的算法?

Posted

技术标签:

【中文标题】硬排序问题 - 我应该使用啥类型的算法?【英文标题】:Hard sorting problem - what type of algorithm should I be using?硬排序问题 - 我应该使用什么类型的算法? 【发布时间】:2011-04-15 01:15:40 【问题描述】:

问题:

N 个节点通过 0 到 1 范围内的“接近度”因子相互关联,其中因子 1 表示两个节点没有任何共同点,而 0 表示两个节点完全相同。

如果两个节点都靠近另一个节点(即它们的因子接近 0),那么这 并不 意味着它们将靠近在一起,尽管从概率上它们确实有更高的在一起的机会。

-

问题:

如果集合中有另一个节点,则在尽可能短的时间内找到离它最近的节点。

这不是家庭作业问题,这是我需要解决的现实问题 - 但我从未参加过任何算法课程等,所以我不知道我应该研究哪种算法。

我可以在添加另一个节点之前索引所有节点并收集每个节点之间的紧密度数据,但是由于无法将所有节点与新节点进行比较,因此我无法提出有效的解决方案。任何想法或帮助将不胜感激:)

【问题讨论】:

各个现有节点之间的距离是否告诉您现有节点和新节点之间的距离可能是多少?如果不是,那么我认为将新节点与所有现有节点进行比较可能是您能做的最好的事情。 从概率上讲,是的,但是对于某些特殊情况的节点来说,这种情况的可能性很小(非常小)。然而,随着节点数量的增加,这个概率变得如此之小,以至于我可以忽略它而不影响结果。 如果您可以将节点视为“空间中的固定位置”,则可以使用八叉树(如果您的空间超过三个维度,则使用 n 维等效项)进行更快的查找,但从你的描述中不清楚他们是否这样做。 它们在太空中确实有固定的位置。但是 9000 维怎么样?效率会是怎样的呢?如果我以这种方式建模,那么每个节点实际上都有 9000 个维度 接近度是否遵循三角不等式?也就是说,对于所有 b,是否 D(a,c) >= D(a,b)+D(b,c)?并且接近度实际上是一个实数,还是可以表示为整数或有理数? 【参考方案1】:

因为您的“紧密度”度量遵循三角不等式,您应该能够使用BK-Trees 的变体来组织您的元素。使它们适应实数应该只是选择一个间隔来量化你的数字,否则使用标准的 Bk-Tree 程序。可能需要进行一些实验 - 例如,您可能希望随着树的进展而提高量化的分辨率。

【讨论】:

谢谢,看起来这种方法只要稍加修改就可以很好地工作。它也是一种有趣的使用方式 - 一旦我完成了所有工作,我会写一篇关于它的博客文章。【参考方案2】:

但没有将所有节点与 我无法访问的新节点 想出一个有效的解决方案

如果没有关于节点之间关系的任何其他信息,这是唯一的方法,因为您必须计算出新节点和每个现有节点之间的紧密度因子。 O(n) 算法可以是一个完美的解决方案。

您可能会考虑的一个附加功能 - 请记住,我们不知道您为对象使用的数据结构 - 是将所有当前节点组织成一个图表,其中具有低于某个阈值的因​​子的节点可以被认为是连接的,所以您可以首先检查更有可能相似/相关的节点。

【讨论】:

【参考方案3】:

如果您想要速度方面的最佳算法,但空间为 O(n^2),则为每个节点创建一个其他节点的排序列表(按紧密度排序)。

当你得到一个新节点时,你必须将它添加到所有其他节点的索引列表中,并且所有其他节点都需要添加到它的列表中。

要找到最近的节点,只需找到任意节点列表中的第一个节点即可。

由于您已经需要 O(n^2) 空间(为了存储您需要的所有接近度信息,基本上是一个 NxN 矩阵,其中 A[i,j] 表示 i 和 j 之间的接近度)您不妨对其进行排序并获得 O(1) 检索。

【讨论】:

谢谢,不幸的是,只有在添加新节点后才会进行检索,因此无论如何都需要先进行排序。可能是我没有使问题描述更清楚的错。【参考方案4】:

如果这种接近形成一个线性频谱(这样接近某物意味着接近于它的其他事物,而不接近意味着不接近那些接近),那么您可以简单地进行二进制或插值排序在插入接近度时,处理一个额外的复杂性:在每个点上,您必须查看接近度是低于还是高于或低于或降低。

例如,如果我们考虑字母 - A 接近 B 但远离 Z - 那么预先存在的元素可以保持排序,例如:A、B、E、G、K、M、Q、Z。要插入说“F”,首先要与中间元素 [3] G 和后面的元素进行比较:[4] K。您确定 F 比 K 更接近 G,因此最佳匹配要么在G 或向左,我们移动到左侧未探索区域的一半... 3/2=[1] B,然后是 E,我们发现 E 更接近 F,所以匹配在 E 或这是正确的。将我们之前在 [3] 和 [1] 处的检查之间的空间减半,我们在 [2] 处进行测试,发现它的距离相等,因此将其插入到两者之间。

编辑:它可能在概率情况下工作得更好,并且需要更少的比较,从光谱的末端开始并按照自己的方式工作(例如,将 F 与 A 和 Z 进行比较,确定它更接近 A,看看 A 是否更接近或中点 [3] G)。此外,最好与二进制/插值引导您的位置两侧最近的几个点进行比较。

【讨论】:

谢谢,经过一番思考,这可能会奏效。它不是线性谱,但概率上它是。目前,您的方法似乎有点像一维排序 - 但增加这种排序发生的维数会降低假设线性错误的可能性。如果我可以将其减少到可以忽略不计的数量,那么它应该比 O(n) 工作得更快 - 如果这有效,那么我可能会写一篇关于我在做什么以及算法如何工作的博客文章 ;) @Jordan:听起来不错。希望您能通过博客文章的链接更新您的问题。干杯。 这假设接近度是一维的(实际上,是一维的)。考虑编辑单词之间的距离,例如:它遵循三角不等式,但不是一维的,甚至不是任何固定维度。 @Nick:是的,这个假设在答案的开头就清楚地表达了。 Ddit 距离确实是一个复杂得多的问题。 @Tony Right,但他说“如果两个节点都靠近另一个节点(即它们的因子接近 0),那么这并不意味着它们将靠近在一起”。您的答案虽然有用,但假设节点的总顺序,这在这里似乎不太可能是正确的。【参考方案5】:

ACM 调查 2001 年 9 月发表了两篇可能相关的论文,至少在背景方面。 “在度量空间中搜索”,主要作者 Chavez,和“在高维空间中搜索 - 用于提高多媒体数据库性能的索引结构”,主要作者 Bohm。从记忆中,如果您只有三角不等式,您可以使用它来达到某种效果,但是如果您可以将数据缩减到合理的维度,您可以通过使用了解此维度结构的搜索结构来做得更好.

【讨论】:

【参考方案6】:

Facebook 有这样的东西,它将你和你所有的朋友放在一个图表中,然后慢慢地移动每个人,直到人们根据共同的朋友分组在一起等等。

在我看来,他们只是让任何 0.5 的东西成为排斥力,并且每次迭代都基于净力来感动人们。经过几百次迭代,它看起来相当不错。

注意:这不是一种算法,它是一种启发式算法。在我看到的 facebook 实现中,两个人无法达到平衡并一直在彼此周围跳舞。事实证明,他们实际上是同一个人,拥有两个不同的帐户。

此外,在一台像样的计算机和大约 100 个节点上大约需要 15 分钟。 YMMV。

【讨论】:

【参考方案7】:

它看起来很像Nearest Neighbor Search 问题(也称为similarity search

【讨论】:

谢谢,这正是我想要的。知道 9000 维版本是否有效吗? - 是的,我是认真的:( 我真的只住在智选假日酒店 - 我与一群非常聪明的机器学习和数学人员一起工作,并且不时学习一些东西。我们在 20 节点的 hadoop 集群上进行 LSH,在 16 节点的 MPP 数据库(都是双六核)上进行 k-means ......我们的数据集相当大。这实际上取决于您拥有多少硬件,但 AFAIK 是完成您想做的事情的最有效方式。

以上是关于硬排序问题 - 我应该使用啥类型的算法?的主要内容,如果未能解决你的问题,请参考以下文章

我想参加高中组NOI的比赛,但是我不知道我应该要掌握一些啥知识,现在我只会C。 如果可以就推荐书或方法

我的 python 递归快速排序算法有啥问题?

qsort 使用啥排序算法?

PHP使用啥排序算法?

在线排序算法和外部排序算法有啥区别?

collection.sort用的是啥排序算法