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

时间:2011-04-15 01:15:40

标签: c++ algorithm sorting

问题:

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

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

-

问题:

如果在集合中放置了另一个节点,请在尽可能短的时间内找到它最接近的节点。

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

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

7 个答案:

答案 0 :(得分:1)

  

但没有比较所有节点   新节点我无法做到   提出有效的解决方案

如果没有关于节点之间关系的任何其他信息,这是您可以执行此操作的唯一方法,因为您必须确定新节点与每个现有节点之间的紧密度因子。 O(n)算法可以是一个非常好的解决方案。

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

答案 1 :(得分:1)

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

获得新节点时,必须将其添加到所有其他节点的索引列表中,并且需要将所有其他节点添加到其列表中。

要查找最近的节点,只需找到任何节点列表中的第一个节点。

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

答案 2 :(得分:1)

如果这种接近形成一个线性光谱(这样接近某些东西意味着接近于其他接近它的东西,并且不接近意味着不接近那些接近的那些),那么你可以简单地进行二元或插值排序在插入接近时,处理一个额外的复杂性:在每个点你必须看到接近度是增加还是减少低于或高于。

例如,如果我们考虑字母 - 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)。此外,最好与二进制/插值所在的两侧最近的几个点进行比较。

答案 3 :(得分:1)

因为您的“亲密度”指标服从三角形不等式,您应该能够使用BK-Trees的变体来组织元素。使它们适应实数应该只是选择一个间隔来量化你的数字,否则使用标准的Bk-Tree程序。可能需要进行一些实验 - 例如,您可能希望在向下进行树时增加量化的分辨率。

答案 4 :(得分:1)

ACM调查2001年9月发表了两篇可能相关的论文,至少在背景方面。 “在公制空间中搜索”,主要作者查韦斯和“在高维空间中搜索 - 索引结构以提高多媒体数据库的性能”,主要作者Bohm。从内存中,如果你只有三角不等式,你可以使用它来实现某些效果,但是如果你可以将数据修剪到合理数量的维度,你可以通过使用了解这个维度结构的搜索结构做得更好

答案 5 :(得分:0)

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

在我看来,他们只是做了什么< 0.5一个吸引力,任何> 0.5一个排斥力,并根据净力每次迭代移动人。经过几百次迭代,它看起来非常好。

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

此外,它在一台体面的计算机和大约100个节点上花了大约15分钟。 YMMV。

答案 6 :(得分:0)

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