C 用蠻力法與分治法解決最近對問題

2021-10-05 08:21:54 字數 3119 閱讀 9091

設 p1(x1,y1),p2(x2,y2),……,pn(xn,yn)是平面上n個點構成的集合s,最近對問題就是找出集合s中距離最近的點對。嚴格地講,最接近點對可能多於一對,簡單起見,只找出其中的一對即可。

簡單起見,只考慮二維的情況並假設所討論的點以標準笛卡爾座標形式給出。因此,兩個點pi(xi,yi)和pj(xj,yj)之間的距離是歐幾里得距離(euclidean distance):

蠻力法求解最近對問題的過程是顯而易見的:分別計算每一對點之間的距離,然後找出距離最小的那一對。為了避免對同一對點計算兩次距離,可以只考慮i**如下:

#include

#include

using

namespace std;

double

closestpoints

(double x,

double y,

int n)}}

cout<<

"最近的點對是

<

","<

">和

<

","<

">,"

;return mindist;

}int

main()

mindist=

closestpoints

(x,y,n)

; cout<<

"其距離為:"

<<

sqrt

(mindist)

<

return0;

}

演算法closestpoints的基本語句是計算兩個點的歐幾里得距離,該語句的主要操作是求平方,其執行次數為:

在利用分治法思想解決此問題時,首先考慮將最近對問題進行分治,設計其分治策略。將集合s分成兩個子集s1和s2,根據平衡子問題原則,每個子集中的點數大致都為n/2。這樣分治後,最近點對將會出現三種情況:在s1中,在s2中或者最近點對分別在集合s1和s2中。利用遞迴分析法分別計算前兩種情況,第三種方法另外分析。求解出三類子情況後,再合併三類情況,比較分析後輸出三者中最小的距離。

**如下:

#include

#include

#include

#include

#include

using

namespace std;

struct point //點結構

;double

distance

(point a,point b)

bool

cmp1

(point a,point b)

//按x座標公升序排列

bool

cmp2

(point a,point b)

//按y座標公升序排列

double

closest

(point s,

int low,

int high,point rec)

if(high-low==2)

//只有三個點,求最近對距離

else

if(d2

else

} mid=

(low+high)/2

;//計算中間點

d1=closest

(s,low,mid,rec)

;//遞迴求解子問題1

temp1[0]

=rec[0]

; temp1[1]

=rec[1]

; d2=

closest

(s,mid+

1,high,rec)

;//遞迴求解子問題2

temp2[0]

=rec[0]

; temp2[1]

=rec[1]

;if(d1

//以下為求解子問題3

else

index=0;

for(i=mid;

(i>=low)

&&(s[mid]

.x-s[i]

.x;i--

)//建立點集合p1

for(i=mid+1;

(i<=high)

&&(s[i]

.x-s[mid]

.x;i++

)//建立點集合p2

sort

(p,p+index,cmp2)

;//對集合p1和p2按y座標公升序排列

for(i=

0;i)//依次處理集合p1和p2中的點

else}}

}return d;

}int

main()

sort

(p,p+n,cmp1)

; point index[2]

; mindist=

closest

(p,0

,n-1

,index)

; cout<<

"最小距離點對為:

<

.x<<

","<

.y<<

">,

<

.x<<

","<

.y<<

">"

<

cout<<

"最小距離為:"

<

//輸出點對的最小問題

return0;

}

應用分治法求解含有n個點的最近對問題,由於劃分階段的情況1和情況2可遞迴求解,情況3的時間代價是o(n),合併子問題解的時間代價是o(1),則演算法的時間複雜性可用下面的遞推式表示:

根據主定理可得:

用分治法解決最近對問題

1.問題描述 給出在同乙個平面內所有點的座標,然後找出這些點中最近的兩個點的距離。2.解析 將所給平面上n個點的集合s分成兩個子集s1和s2,每個子集中約有n 2個點。然後在每個子集中遞迴地求最接近的點對。在這裡,乙個關鍵的問題是如何實現分治法中的合併步驟,即由s1和s2的最接近點對,如何求得原集合...

分治法和蠻力法MATLAB求最近點對

主程式 main.m clear clc n 20 隨機生成20個點 a rand n,2 10 將20個點按橫座標公升序排列 a sortrows a,1 蠻力法求隨機點的最近點對 mindist,x1,x2 bcloest a,1,n mindist1,y1,y2 cloest a,1,n 使用...

最近點對(蠻力法)

include rand and srand include include sqrt include int max include define distance x1,y1,x2,y2 sqrt x1 x2 x1 x2 y1 y2 y1 y2 define max 10 生成點的個數 stru...