问题:
我们在3D欧几里德空间中有一组n个顶点,并且偶数个顶点。
我们希望根据它们的接近程度将它们配对。换句话说,我们希望能够找到一组顶点对,其中每对顶点尽可能接近。
我们希望尽可能减少牺牲任何其他对的顶点之间的接近程度。
我不是在寻找最最佳解决方案(如果它甚至严格存在/可以完成),只是一个可以相对快速计算的合理解决方案。
< / LI>相对可怕的蛮力方法包括选择一个顶点并循环通过其余部分找到它最近的邻居,然后重复直到没有剩下。当然,当我们接近列表的末尾时,最近的顶点可能会很远,但它是唯一的选择,因此这可能会在上面的第三点上严重失败。
答案 0 :(得分:4)
由于您没有寻找最佳解决方案,因此这是您可以考虑的启发式方法。
对于每个点p,计算两个点:最近的邻居和最远的邻居,分别距离最近和最远。现在让q为具有最大最远邻居的点(q是输入中的极值点)。将q与其最近邻居匹配,删除它们并递归计算剩余点的匹配。
这当然不是最优的,但它似乎在小输入集上做得相当好。如果您需要最佳解决方案,请阅读euclidean matching problem。
答案 1 :(得分:4)
此类问题的常见方法(尤其是当n很大时)是预先计算空间索引结构,例如kd tree或octtree并执行{{3}的搜索在它的帮助下。通过octtree的节点,可用点被放入箱中,因此您可以确定它们是相互靠近的。您也可以最大限度地减少比较次数。
使用octtree实现的草图:您需要一个存储其边界框的Node类。派生的LeafNode类存储最多(例如k = 20)的少量点,这些点添加有插入函数。派生的NonLeafNode类存储对8个子节点的引用(可能是Leaf和NonLeafNodes)。
树由根节点表示,所有插入和查询从此处开始。通过从插入到LeafNode中的前k个点开始构建树。如果插入了第k + 1点,则边界框被分成8个子框,并且包含的点被分类到它们中。当前的LeafNode被一个具有8个子节点的NonLeafNode替换。 这将迭代,直到所有点都在树中。
对于最近邻居搜索,通过与边界框比较,从根节点开始遍历树。如果查询点位于节点的边界框内,则遍历将进入该节点。请注意,如果找到最近的候选者,则还需要检查octtree中的相邻节点。
对于kdtree实现,请查看维基百科页面,看起来非常困难。