【問題描述】
最近對問題要求在包含有n個點的集合s中,找出距離最近的兩個點。設 p1(x1,y1),p2(x2,y2),……,pn(xn,yn)是平面的n個點。
嚴格地將,最近點對可能不止一對,此例輸出一對即可。
【基本演算法思想】
暴力法:
在蠻力法實現最近點對問題中,將問題簡化:距離最近的點對可能多於一對,找出一對即可,另外只考慮二維平面中的情況。此處考慮到
直接用公式計算其距離(歐幾里得距離):
通過遍歷所有點集,計算出每乙個點對的距離,計算出最近的距離並輸出。避免同一對點計算兩次,只考慮i
分治法:
在利用分治法思想解決此問題時,首先考慮將最近對問題進行分治,設計其分治策略。將集合s分成兩個子集s1和s2,根據
平衡子問題原則,每個子集中的點數大致都為n/2。這樣分治後,最近點對將會出現三種情況:在s1中,在s2中或者最近
點對分別在集合s1和s2中。利用遞迴分析法分別計算前兩種情況,第三種方法另外分析。求解出三類子情況後,
再合併三類情況,比較分析後輸出三者中最小的距離。
***複雜度分析***: 在分治演算法中,當求解n個點的集合的最近點對時,對於上述三類情況中的前兩者可由遞迴算得,
而分析可得第三類情況的時間代價 ,合併後問題求解的總的時間按複雜度可由下列公式來:
【源**】
//最近點對問題,蠻力法實現(c++)
#include
#include
#include
#include
#define max 99999
using
namespace
std;
double closestpoints(double x,double y,int n)
int main()
//分治法求解最近點對問題(c++)
#include
#include
#include
#include
#include
using
namespace
std;
struct point;
double distance(point a,point b)
bool cmp(point a,point b)
if(high-low==2)
else
if(d20].x=s[low+1].x;rec[0].y=s[low+1].y;
rec[1].x=s[high].x;rec[1].y=s[high].y;
return d2;
}else
}mid=(low+high)/2; //其他情況遞迴
d1=closestpoint(s,low,mid,rec);
temp1[0]=rec[0];
temp1[1]=rec[1];
d2=closestpoint(s,mid+1,high,rec);
temp2[0]=rec[0];
temp2[1]=rec[1];
if(d10]=temp1[0];
rec[1]=temp1[1];
}else
index=0;
for(i=mid;(i>=low)&&((s[mid].x-s[i].x)//點集合p1
p[index++]=s[i];
for(i=mid+1;(i<=high)&&((s[i].x-s[mid].x)//點集合p2
p[index++]=s[i];
sort(p,p+index,cmp); //公升序排列
for(i=0;ifor(j=j+1;jif((p[j].y-p[i].y)>=d)
break;
else }}
}return d;
}int main()
演算法分析與設計 最近點對問題
問題分析 這個題目目前對於大家會有點難度,有興趣的同學可以研究一下,這種題目才是分治的精髓所在。前段時間 partychen 到吳涇去買東西,發現在步行街有乙個賭博遊戲,乙個商人在地面上擺放了很多的小禮品,然後準備了很多大小相同的圓環,玩家可以到商人處花 5 塊錢買乙個圓環。然後站在一根白線外使用圓...
演算法分析與設計5最近點對
在含有n個點的集合p中找出最近的兩個點的距離 採取分治策略,利用遞迴將問題反覆拆分為兩個子集,再對每個子集分別進行計算分析,然後合併比較得出最近點對間的距離 if n 2 mid high low 2 dist1 closestpoint p,low,mid dist2 closestpoint p...
演算法設計與分析之最近對問題
設p1 x1,y1 p2 x2,y2 pn xn,yn 是平面上n個點構成的集合s,設計演算法找出集合s中距離最近的點對。1 進一步掌握遞迴演算法的設計思想以及遞迴程式的除錯技術 2 理解這樣乙個觀點 分治與遞迴經常同時應用在演算法設計之中。1 分別用蠻力法和分治法求解最近對問題 2 分析演算法的時...