問題
設p1(x1, y1),p2(x2, y2),p3(x3, y3), p4(x4, y4) …,是平面上n個雜湊點構成的集合s,最近對問題就是找出集合s中距離最近的點對。
解析設s中的點為平面上的點,它們都有2個座標值x和y。為了將平面上點集s線性分割為大小大致相等的2個子集s1和s2,我們選取一垂直線l:x=m來作為分割直線。其中m為s中各點x座標的中位數。由此將s分割為s1=和s2=。從而使s1和s2分別位於直線l的左側和右側,且s=s1∪s2 。由於m是s中各點x座標值的中位數,因此s1和s2中的點數大致相等。遞迴地在s1和s2上解最接近點對問題,我們分別得到s1和s2中的最小距離d1和d2。現設d=min(d1,d2)。若s的最接近點對(p,q)之間的距離d(p,q)設計
double closest(vector&vx, int lo, int hi)
return distance(vx[lo],vx[hi-1]);
} if(hi - lo == 3));
} int m = (lo + hi) / 2;
double mx = vx[m].x;
double dl = closest(vx,lo,m);
double dr = closest(vx,m,hi);
double d = min(dl,dr);
merge(vx,lo,m,hi);
vectorvp;
for(int i = lo; i < hi; ++i)
for(int i = 0; i < vp.size(); ++i)
} }return d;
}
分析
時間複雜度為nlogn 原始碼
#include#include#include#include#include#includeusing namespace std;
struct point;
inline bool compx(const point &p1, const point &p2)
inline bool compy(const point &p1, const point &p2)
inline double distance(const point &a, const point &b)
void merge(vector&v, int lo, int m, int hi)
}double closest(vector&vx, int lo, int hi)
return distance(vx[lo],vx[hi-1]);
} if(hi - lo == 3));
} int m = (lo + hi) / 2;
double mx = vx[m].x;
double dl = closest(vx,lo,m);
double dr = closest(vx,m,hi);
double d = min(dl,dr);
merge(vx,lo,m,hi);
vectorvp;
for(int i = lo; i < hi; ++i)
for(int i = 0; i < vp.size(); ++i)
} }return d;
}int main()
sort(v.begin(),v.end(),compx);
cout << closest(v,0,v.size()) << endl;
return 0;
分治法求解最近點距
最近點對問題很簡單,就是給定一堆點 這裡是二位座標下 求解最近的點的距離,該問題可以用窮舉法求解,雙重迴圈就夠了,就不說了,主要看一下分治法的 也很簡單,有注釋。如下 採用c 類模板編寫 編譯環境vs2015 include include include math.h include using ...
分治法求最近點對問題
分治法 1 演算法描述 已知集合s中有n個點,分治法的思想就是將s進行拆分,分為2部分求最近點對。演算法每次 選擇一條垂線l,將s拆分左右兩部分為sl和sr l一般取點集s中所有點的中間點的x座標來劃分,這樣可以保證sl和sr中的點數目各為n 2,否則以其他方式劃分s,有 可能導致sl 和sr中點數...
分治法求最近點對問題
1 演算法描述 已知集合s中有n個點,分治法的思想就是將s進行拆分,分為2部分求最近點對。演算法每次 選擇一條垂線l,將s拆分左右兩部分為sl和sr,l一般取點集s中所有點的中間點的x座標來劃分,這樣可以保證sl和sr中的點數目各為n 2,否則以其他方式劃分s,有 可能導致sl 和sr中點數目乙個為...