最近點問題

2021-06-26 08:08:06 字數 3057 閱讀 1047

求點集中的最近點對有以下兩種方法:

設p1=(x1, y1), p2=(x2, y2), …, pn=(xn, yn)是平面上n個點構成的集合s,設計演算法找出集合s中距離最近的點對。

1、蠻力法(適用於點的數目比較小的情況下)

1)演算法描述:

已知集合s中有n個點,一共可以組成n(n-1)/2對點對,蠻力法就是對這n(n-1)/2

對點對逐對進行距離計算,

通過迴圈求得點集中的最近點對:

2)**描述:

[cpp]view plain

copy

print?

double

mindistance = 

double

.maxvalue;  

//設定乙個mindistance儲存最近點對的距離,初始值為無窮大

intpointindex1,pointindex2; 

//設定pointindex1,pointindex2分別儲存最近點對的兩個點編號

for(i=1; i

//迴圈計算n(n-1)/2對點對的距離

}  }  

3)演算法時間複雜度:演算法一共要執行 n(n-1)/2次迴圈,因此演算法複雜度為o(n2)

2、分治法

1)演算法描述:

已知集合s中有n個點,分治法的思想就是將s進行拆分,分為2部分求最近點對。演算法每次

選擇一條垂線l,將s拆分左右兩部分為sl和sr,l一般取點集s中所有點的中間點的x座標來劃分,這樣可以保證sl和sr中的點數目各為n/2,

(否則以其他方式劃分s,有

可能導致sl

和sr中點數目乙個為1,乙個為n-1,不利於演算法效率,要盡量保持樹的平衡性)

依次找出這兩部分中的最小點對距離:δl和δr,記sl和sr中最小點對距離δ = min(δl,δr),如圖1:

以l為中心,δ為半徑劃分乙個長帶,最小點對還有可能存在於sl和sr的交界處,如下圖2左圖中的虛線帶,p點和q點分別位於sl和sr的虛線範圍內,在這個範圍內,p點和q點之間的距離才會小於δ,最小點對計算才有意義。

對於sl虛框範圍內的p點,在sr

虛框中與p點距離小於δ的頂多只有六個點,就是圖二右圖中的2個正方形的6的頂點。這個可以反推證明,如果右邊這2個正方形內有7個點與p點距離小於

δ,例如q點,則q點與下面正方形的四個頂點距離小於

δ,則和δ為

sl和s

r中的最小點對距離相矛盾。因此對

於sl虛框中的p點,不需求出p點和右邊虛線框內所有點距離,只需計算sr中

與p點y座標距離最近的6個點,就可以求出最近點對,節省了比較次數。

(否則的話,

最壞情形下,在s

r虛框中有可能會有n/2個點,對於s

l虛框中的p點

,每次要比較n/2次,浪費了演算法的效率

)**描述:

1)對點集s的點x座標和y座標進行公升序排序,獲得點集sx和sy

2)令δ

=∞;  //δ為最小點位距離

3)divide_conquer(sx,sy

,δ) //分治法

if (sx.count=1) thenδ=∞;    //如果sx

中只有乙個點,則δ=∞

returnδ;

else if(sx.count=2 and d(sx.[0],sx.[1])

中只有2個點,則δ為兩點之間距離

δ=d(sx.[0], sx.[1]); 

return δ;

else   //如果sx

中多於2個點,則將sx

,sy分治,以中心點畫線,將sx

分為左右兩部分sxl

和sxr

,sy分為syl和s

yr j1=1,j2=1,k1=1,k2=1;

mid =sx.count/2;   //mid為sx

中的中間點點號

l =sx.[mid].x;      //l為sx

中的中間點x座標

for(i=1,ix.count,i++)

δl = divide_conquer(sxl,syl

,δ);   //獲取sx

中的的最小點位距離δl

δr = divide_conquer(sxr,syr

,δ);  //獲取sy

中的的最小點位距離δr

δ= min (δl,δr);

δ=merge(syl,syr

,δ);   //獲sx

中sy交界處的最小點位距離,並綜合 δl

和δr 求出點集的最小點位距離δ

returnδ;

函式merge(syl,syr

,δ)merge(syl,syr

,δ)

for(i=1,iyr.count,i++)  //獲取syr

中在右邊虛框(距離小於δ)內的點,存入到s'yr中,新陣列保持原來的公升序性質

t=1;

for(i=1,iyl.count,i++)

for( j= max(1,t-3), j<=min(t+3,s'yr.count),j++)   //計算s'yr中的點與s'yl[t]y座標相鄰的六個點的距離

return δ }

3)演算法時間複雜度:

首先對點集s的點x座標和y座標進行公升序排序,需要迴圈2nlogn次,複雜度為o(2nlogn)

接下來在分治過程中,對於每個s'yl中的點,都需要與s'yr中的6個點進行比較

o(n)= 2o(n/2) + (n/2)*6  (乙個點集劃分為左右兩個點集,時間複雜度為左右兩個點集加上中間區域運算之和)

其解為o(n)< o(3nlogn)

因此總的時間複雜度為o(3nlogn),比蠻力法的o(n2)要高效。

最近點對問題

在n n 1 個點的集合中尋找最近點對。即求任意兩點的歐幾里得距離的最小值。1 最簡單的暴力搜尋演算法,時間複雜對為o n n 2 這裡主要考慮分治演算法,執行時間的遞迴式為t n 2 t n 2 o n 時間複雜度為o n lgn 演算法思想 將集合中的點按x座標排序,我們可以想象一條垂直的直線將...

最近點對問題

在二維平面上的n個點中,如何快速的找出最近的一對點,就是最近點對問題。一種簡單的想法是暴力列舉每兩個點,記錄最小距離,顯然,時間複雜度為o n 2 在這裡介紹一種時間複雜度為o nlognlogn 的演算法。其實,這裡用到了分治的思想。將所給平面上n個點的集合s分成兩個子集s1和s2,每個子集中約有...

最近點對問題

最近點對問題,是分治法的乙個典型應用,可以作為分治法入門的乙個切入點。最近點對問題的描述比較簡單,在二維平面中,給定一堆點,求距離最近的一對點,思路是,講這一堆點分為兩部分,左域與右域,如何劃分左域右域呢?我們知道,這一堆點,每乙個點都有其橫座標,假如有十個點,對應十個橫座標,我們就取其中間數,然後...