C++ 硬排序问题-我应该使用哪种类型的算法?

C++ 硬排序问题-我应该使用哪种类型的算法?,c++,algorithm,sorting,C++,Algorithm,Sorting,问题: N个节点通过范围从0到1的“接近度”因子相互关联,其中因子1表示两个节点没有共同点,0表示两个节点完全相同 如果两个节点都靠近另一个节点(即,它们的系数接近于0),则这并不意味着它们将靠近,尽管从概率上讲,它们确实有更高的机会靠近 - 问题: 如果集合中放置了另一个节点,请在尽可能短的时间内找到它最近的节点 这不是一个家庭作业问题,这是一个我需要解决的现实世界问题——但我从未参加过任何算法课程,所以我不知道我应该研究哪种算法 我可以在添加另一个节点之前对所有节点进行索引,并收集每个节点之

问题:

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

如果两个节点都靠近另一个节点(即,它们的系数接近于0),则这并不意味着它们将靠近,尽管从概率上讲,它们确实有更高的机会靠近

-

问题:

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

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


我可以在添加另一个节点之前对所有节点进行索引,并收集每个节点之间的接近度数据,但除了将所有节点与新节点进行比较之外,我还无法找到有效的解决方案。任何想法或帮助都将不胜感激:)

Facebook有一个功能,它将你和你所有的朋友放在一个图表中,然后慢慢地移动每个人,直到人们根据共同的朋友分组,依此类推

在我看来,他们只是把任何0.5的东西变成了一种排斥力,并在基于净力的每一次迭代中移动人们。经过几百次迭代后,它看起来相当不错

注意:这不是一个算法,而是一个启发式算法。在我看到的facebook实现中,两个人无法达到平衡,一直在相互跳舞。事实证明,他们实际上是同一个人,有两个不同的账户

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

但缺少将所有节点与 新的节点我还没有找到 想出一个有效的解决办法

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


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

如果您希望在速度方面获得最佳算法,但需要O(n^2)空间,则为每个节点创建其他节点的排序列表(按接近度排序)

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

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


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

这看起来像个可疑的问题(也称为
相似性搜索

如果这种接近形成了一个线性光谱(接近某事物意味着接近其他接近它的事物,而不接近则意味着不接近那些接近的事物),那么你只需在插入时对接近度进行二进制或插值排序,处理一个额外的复杂性:在每一点上,你都必须看看亲密度是在低于还是高于之下增加还是减少

例如,如果我们考虑字母A接近B但远离z,则预先存在的元素可以保持排序,例如:A、B、E、G、K、M、Q、Z.插入“f”,首先通过与中间元素比较,[3 ] g,然后跟随一个:(4)K. You建立F更接近G than K,所以最好的匹配要么在G,要么在左边,我们移动一半到左边未探测的区域。。。3/2=[1]B,后跟E,我们发现E更接近F,所以匹配要么在E,要么在它的右边。将前面在[3]和[1]的检查之间的间距减半,我们在[2]进行测试,发现它的距离相等,所以将它插入到这两者之间


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

因为“贴近度”指标遵循三角形不等式,所以应该能够使用的变量来组织元素。使它们适应实数应该只是选择一个区间来量化你的数字,或者使用标准的Bk树程序。可能需要一些实验——例如,当你沿着树往下走的时候,你可能想提高量化的分辨率。

ACM调查2001年9月发表了两篇可能相关的论文,至少对于背景而言。“在度量空间中搜索”,主要作者查韦斯,和“在高维空间中搜索-提高多媒体数据库性能的索引结构”,主要作者博姆。根据记忆,如果你只有三角形不等式,你可以用它来发挥作用,但是如果你能把数据缩减到合理的维数,通过使用了解此维度结构的搜索结构,您可以做得更好。

各种现有节点之间的距离是否告诉您现有节点与新节点之间的距离?如果没有,那么我认为将新节点与所有现有节点进行比较可能是最好的选择