分治法高效求解最邻近点对间的最短距离

2.1.5 ClosedShortestPoint

        求平面内N个点中,相距最近的两个顶点之间的距离。

(1)求解该问题,实际上就是比较其中每一个顶点与其他N-1个顶点之间的距离,然后比较计算出其中最短的距离。因此归根到底还是比较一堆数的大小,只不过多了一个数之间的计算。所以,可以想到能不能用分治法将所有点进行分割。

(2)如果是一堆杂乱无章的点,杂乱无章的存储在vector中,那么我们如何对这些点进行分割了?就这个问题,让我整整想了2天,一开始面对这个问题,脑海中有很多种想法,但是你不知道,也不确定,到底哪种想法,哪种解法是正确的思路。因此想来想去都无从下手,一提起笔就面对存储在vector中杂乱无章的点时,就感觉无法用分治思想来求解,因为之前在用分治法求解无序的数时,可以对数进行不断的中间分隔;而顶点是杂乱无章的存储,如果直接从vector中间来分,那么左边的点的距离,可能左边中有顶点a与右边中的顶点b挨的比较近,而一旦被划分开来了,那么顶点a 和顶点b就永远不会再进行比较,因为左边的就只会不断的分割比较左边的,而右边的就只会不断分割比较右边的;当然中间的也要进行比较,如果对左右所有的点都比较当然可以得到最优解,但是时间复杂度就是O(n2),可以比较靠近划分中线左右两边的点的距离,但是如果点是杂乱存储的,感觉这种比较没什么意义。

突然,脑海中冒出一个想法,就是将所有点先按大小进行排序存储,但是,问题又来了,如何对这些顶点进行排序了,当时的一个想法是按照顶点到原点的距离进行排序,这个想法好像可以,但是你会发现,这些点在y轴左右两边被正确的划分,而在某一边的排序依然不能正确按照某个中线进行区分,因为若两个顶点都离原点很远,可能一个离y轴很近,另一个离y轴很远。如果只是按照离y轴的远近来划分,那么可以直接按照x坐标进行排序存储在vector,这样所有的顶点可按照与y轴平行的中轴线进行左右的划分,则左边的顶点就不必都要和右边的顶点进行比较,因为很明显,左边的顶点跨过中轴线与右边的顶点进行比较时,距离肯定会增大,但是有一个关键点,若左右两边中有存在点都与中轴线挨的比较近,那么左右两边的点就需要进行比较。

那么关于中间的点如果进行比较呢?如果左右两边都进行比较,那么时间复杂度就为O(n2),即使对中间的顶点进行限定,即我们限定一个范围,左右两边离中间分割线为一定距离内的点进行左右比较,但是,这种情况仍然会出现时间复杂度为O(n2)的情况,因为有可能所有的顶点都在选定的中线范围内。那么到底该如何选定区域呢,如何比较呢?

关于如何选区域的问题,已存在一种解题的trick但又正确的思路,就是将区域的宽度width<=d,其中d 为左右两边中当前距离最小者;因为大于d的点,则距离更远;而在范围d,也可能存在n-1个点,如果都进行比较,那么时间复杂度也为O(n2),但是trick就在于只需要最多与对面6个点进行比较即可:因为与对面6个点占用的空间之外的点,距离当前比较点的距离绝对大于d,所以之外的就无需比较,时间复杂

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值