演算法思路:
資料預處理。先把點集中的所有點,按照y座標大小從左往右排序,得到關於y軸的有序點集合。具體使用stl的qsort方法,自定義比較函式。
使用分治的思想, 把點集分開出來求解。先選取點集中y座標最中間的點,該點所在垂直於y軸的平面把點集劃分成兩個子點集leftsubset和rightsubset,然後分別計算兩個子點集中最短的點對。以此類推,分到子點集僅包含3個點以下。當子點集小於等於3個點時,使用暴力遍曆法求解這些點對的最短距離。
「分」求出leftsubset和rightsubset的最短距離currentmin後,「治」的方法是,把y座標與切平面的距離小於currentmin的點取出,分成l_middle和r_middle。因為只有這些點才有可能構成兩個子點集的最短距離點對。接著對l_middle中的每乙個點來說,只有與r_middle中點的x座標和z座標小於currentmin的點才有可能是最短距離點。分別計算他們的歐幾里得距離,將距離最小的點對記錄下來,更新currentmin。
為了能找出所有最短距離相等的點對,這裡使用了乙個stack全域性變數把最短距離點對儲存起來,每次計算出比stack中的點對距離還要小的點對時,把stack清空,把新點對壓進stack。如果距離一樣,則繼續往stack中放。
**實現:
1 #include2 #include3 #include4 #include5view code#define maxn 100
6using
namespace
std;78
struct
pointdataset[maxn];
1314 stackresultpairs;
1516
int cmp(const
void *a, const
void *b)
1920
double distance(const point &p1, const point &p2)
2324
double findmindistance(int left_m, int right_m, int
n)47
else54}
55}56else60}
61}62}
63return
mindistance;64}
65else
84if((i > middle) && (dataset[i].y - middley <=currentmindistance))87}
8889 vector::iterator end =l_middle_points.end();
90 vector::iterator end2 =r_middle_points.end();
9192
double newdis =int_max;
93for(vector::iterator it = l_middle_points.begin(); it != end; ++it)
112else
119}
120}
121else
125}
126}
127}
128}
129 mindistance =currentmindistance;
130return
mindistance;
131}
132}
133134
intmain()
150151
//快速排序點集
152 qsort(dataset, maxn, sizeof(dataset[0
]), cmp);
153154
//查詢最短距離,並將所有距離相等的點對壓入resultpairs
155double mindis = findmindistance(0, maxn - 1
, maxn);
156157 cout<
shortest distance is:
"158 cout<
\nall closest pairs are:
"<
159160
point a;
161while(!resultpairs.empty())
169170
171 finish=clock();
172 totaltime=(double)(finish-start)/clocks_per_sec;
173 cout<
\nit runs
"seconds!
"<
174return
0;
175 }
演算法分析與實踐 作業5 最近點對問題
p為笛卡爾平面上n 1個點構成的集合,求最近的兩個點的距離 n 2k 蠻力演算法 將每個點與其他點進行計算,求得最短的距離 但需要兩層遍歷,複雜度較高 分治演算法 把點集p 點個數為n 按照x軸從小到大排列 當n 3時,使用蠻力演算法 當n 3時,將點集分為左右大小為 n 2 和 n 2 的子集pl...
最近點對問題
在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,每個子集中約有...