平面最近點距離問題 分治法

2022-05-17 14:04:31 字數 1619 閱讀 2974

演算法:   

0:把所有的點按照橫座標排序   

1:用一條豎直的線l將所有的點分成兩等份  

2:遞迴算出左半部分的最近兩點距離d1,右半部分的最近兩點距離d2,取d=min(d1,d2)   

3:算出「乙個在左半部分,另乙個在右半部分」這樣的點對的最短距離d3。

4:結果=min(d1,d2,d3)    

關鍵就是這第3步。貌似這需要n^2的時間,把左邊每個點和右邊每個點都對比一下。其實不然。秘密就在這裡。    首先,兩邊的點,與分割線l的距離超過d的,都可以扔掉了。   其次,即使兩個點p1,p2(不妨令p1在左邊,p2在右邊)與分割線l的距離(水平距離)都小於d,如果它們的縱座標之差大於d,也沒戲。  就是這兩點使得搜尋範圍大大減小:   對於左半部分的,與l的距離在d之內的,每個p1來說:右半部分內,符合以上兩個條件的點p2最多只有6個!  原因就是:   d是兩個半平面各自內,任意兩點的最小距離,因此在同乙個半平面內,任何兩點距離都不可能超過d。   我們又要求p1和p2的水平距離不能超過d,垂直距離也不能超過d,在這個d*2d的小方塊內,最多只能放下6個距離不小於d的點。    因此,第3步總的比較距離的次數不超過n*6。   

第3步的具體做法是:    

3.1 刪除所有到l的距離大於d的點。 o(n)  

3.2 把右半平面的點按照縱座標y排序。 o(nlogn)  

3.3 對於左半平面內的每個點p1,找出右半平面內縱座標與p1的縱座標的差在d以內的點p2,計算距離取最小值,算出d3。 o(n*6) = o(n)    因為3.2的排序需要o(nlogn),   所以整個演算法的複雜度就是o(n((logn)^2))。    

/*

* 最近點對問題,時間複雜度為o(n*logn*logn)

*/#include

#include

#include

#include

#include

using

namespace

std;

const

double inf =1e20;

const

int n = 100005

;

struct

point

point[n];

intn;

inttmpt[n];

bool cmpxy(const point& a, const point&b)

bool cmpy(const

int& a, const

int&b)

double min(double a, double

b)

double dis(int i, int

j)

double closest_pair(int left, int

right)

sort(tmpt,tmpt+k,cmpy);

//暴力搜尋 tmpt中的最短距離

for(i = 0; i < k; i++)

} return

d;

}

intmain()

return

0;

}

平面最近點對問題 分治

在與聯盟的戰鬥中屢戰屢敗後,帝國撤退到了最後乙個據點。依靠其強大的防禦系統,帝國擊退了聯盟的六波猛烈進攻。經過幾天的苦思冥想,聯盟將軍亞瑟終於注意到帝國防禦系統唯一的弱點就是能源 該系統由n個核電站 能源,其中任何乙個被摧毀都會使防禦系統失效。將軍派出了n個 進入據點之中,打算對能源站展開一次突襲。...

平面最近點對問題 分治

1 演算法描述 已知集合s中有n個點,一共可以組成n n 1 2對點對,蠻力法就是對這n n 1 2對點對逐對進行距離計算,通過迴圈求得點集中的最近點對 2 演算法時間複雜度 演算法一共要執行 n n 1 2次迴圈,因此演算法複雜度為o n2 實現 利用兩個for迴圈可實現所有點的配對,每次配對算出...

分治法求平面最近點對入門

一.平面最近點對問題.平面最近點對 在乙個平面上有n nn個點,求出距離最近的兩個點.平面最近點對是計算幾何中乙個十分經典且基礎的問題,通常採用分治法來解決.二.直線最近點對的分治法.在用分治法解決平面最近點對之前,我們用分治法來解決一下直線最近點對問題.考慮在一條直線上暴力列舉兩個點並計算距離取最...