求最近點對 就我所知道的 有三種演算法,一是演算法導論上給出的,用分治思想,時間複雜度為o(n log(n)),詳細可見演算法導論
第二種是網上給出的 隨機演算法 時間複雜度為o(n ),
原文如下:
對於給定的平面上的n個點(xi,yi)( i=1,2,…,n)和乙個距離d,
以d為尺寸可以構造乙個(邏輯上的)網格,
該網格以(min,min)為網格的最左下點,
之後以步長d不斷向右、向上伸展為長方形網格;
使得(max,max)也含在其中。
由於所有的點均在長方形網格中,最近點對也必在其中。
對每個尺寸為d×d的方格,分別向左向上、向右向上、向左向下、
向右向下各擴充套件一格,可得4個2d×2d的方格 (i=1,2,3,4)。
定理:設已知平面上的某兩點的距離為d。
若最近點對中的乙個點落在某個d×d方格 中,
則在上述的4個2d× 2d方格 (i=1,2,3,4)中,
至少有乙個同時含有最近點對的兩個點。
推論:若已知平面上的某兩點的距離為d,
且演算法對長方形網格中每乙個2d×2d方格中的所有點對,
均一一計算其距離,則該演算法一定可以找出最近點對。
演算法:在點集s(|s|=n)中隨機地取乙個子集t,使得|t|= ë û。
(按隨機取樣演算法的分析,n個中取m個(m≤n)時間為o(n))
對t中的所有點對逐一計算距離,求出最近點對距離d(t)。
(點對數為ë û( ë û-1)/2,每個點對計算時間為o(1),
故總的計算時間為o(ë û2)= o(n)。)
以d(t)為尺寸構造乙個(邏輯上的)長方形網格,
(設長方形的橫向共有m格,縱向共有r格。)
如果m*r≤cn(c可取2~10,取何值合適見後面的討論),
則開設乙個m×r的指標矩陣p、和乙個m×r的計數矩陣q,
然後逐一掃瞄s中的點sk:
如果sk落在方格 中(i,j分別表示所在方格橫向、縱向位置),
則把該點放入p[i,j]所指的鍊錶內,q[i,j]增1,
直至n個點全部檢查為止。
(每個點計算時間為o(1),故總的計算時間為o(n)。)
然後掃瞄q陣列,找到含頂點最多的方格 。(時間為o(n))
如果 中點數≤ ,則逐一計算 中的點距離(時間為o(n)),
求出其中的最近點對及新的d』(如果d』比d小的話)。
如果 中點數> ,則把 一分為4,成為4個 × 的方格,
找出其中含點最多的方格,一直拆分到方格中的點數≤ ,
求出其中的最近點對及新的d』(時間複雜度期望值是o(n))。
若m*r>cn,則在素數表中找乙個略小於cn的素數p,
然後逐一檢查s中的點sk,找到其所在方格 (時間為o(n)),
用雜湊函式h(i,j,p)把sk雜湊至長為p的桶中:
桶中的每個槽只對應乙個方格 (若發生衝突,用衝突處理機制),
每個槽要記錄方格中點的個數,各個點用鍊錶連線起來。
s的檢查完成以後,找到含點數最多的 方格(時間為o(n)),
用前述方法計算出該方格中的最近點對和新d』(如果d』比d小的話)。
以新d』為尺寸構造乙個(邏輯上的)新網格,
設網格中的小方格數為m』×r』,則在這個網格中
恰有(m』-1)×(r』-1)個尺寸為2d』×2d』的方格。
由定理知,最近點對必定落在某個 之中。
逐一檢查s中的點,依次把這些點放入(m』-1)×(r』-1)個指標
所指的鍊錶中(或長度為p的雜湊表中)。(時間複雜度是o(n))
6) 逐一檢查含有2個點以上的方格 ,
對方格中的所有點對進行計算,與當前最小的d*比較,
若小於d*,則更新d*、更新當前的最近點對。
當所有含2個點以上的2d×2d方格檢查完畢時,
點集中的最近點對也就找到了。根據概率分析,
此項工作的時間複雜度期望值是o(n)。
關於c的取值(c可取2~10):
c取值大的好處是需要雜湊的可能性降低,可直接處理二維表,
且每乙個格仔中的頂點數相對要少,第6步中工作量減少;
壞處是迴圈次數增多。c取的小的好處、壞處則反之。
一般來說,若頂點較密集,則c要取的稍大。
(說來慚愧,我剛開始沒看懂,曉文看懂後給我講的,感謝他)
第三種是老楊上課講的,時間複雜度也為o(n log(n)), 感覺借鑑了上訴兩種思想,和第一種的劃分方式有所不同,演算法導論上是用垂線劃分,老楊用面積劃分,一次劃分一半找到含點數最多的面積,在進行劃分,直到省兩個點,找到最近距離,然後按照 上訴第二種中的方法以此距離做網格,以點的橫縱座標分別排序,找相鄰兩點的最短距離(在中距離是用了技巧,當橫座標或是縱座標的差的絕對值大於前面找的距離時,不進行比較,直接排除)。最後找到的最短距離即是所求。
分治演算法求最近點對
先說下題意,很簡單,給n個點的座標,求距離最近的一對點之間距離的一半。第一行是乙個數n表示有n個點,接下來n行是n個點的x座標和y座標,實數。這個題目其實就是求最近點對的距離。演算法導論 上有詳細講解,王曉東的書上也有 主要思想就是分治。先把n個點按x座標排序,然後求左邊n 2個和右邊n 2個的最近...
分治演算法求最近點對
1 演算法描述 已知集合s中有n個點,分治法的思想就是將s進行拆分,分為2部分求最近點對。演算法每次 選擇一條垂線l,將s拆分左右兩部分為sl和sr,l一般取點集s中所有點的中間點的x座標來劃分,這樣可以保證sl和sr中的點數目各為n 2,否則以其他方式劃分s,有 可能導致sl 和sr中點數目乙個為...
分治演算法求最近點對
先說下題意,很簡單,給n個點的座標,求距離最近的一對點之間距離的一半。第一行是乙個數n表示有n個點,接下來n行是n個點的x座標和y座標,實數。這個題目其實就是求最近點對的距離。演算法導論 上有詳細講解,王曉東的書上也有 主要思想就是分治。先把n個點按x座標排序,然後求左邊n 2個和右邊n 2個的最近...