最近點對問題很簡單,就是給定一堆點(這裡是二位座標下),求解最近的點的距離,該問題可以用窮舉法求解,雙重迴圈就夠了,就不說了,主要看一下分治法的**,**也很簡單,有注釋。
**如下:
採用c++類模板編寫
編譯環境vs2015
#include
#include
#include"math.h"
#include
using
namespace
std;
//定義pointx以及pointy類,設定其編號,x,y座標以及<=運算子,主要是因為
//按x座標排序和按y座標排序時所比較的座標不相同,因此不能採用同乙個類。
//採用兩個類可簡化演算法的複雜度。
class pointx
public:
int id;
float x, y;
};class pointy
public:
int p;
float x, y;
};//通過模板可使函式的通用性更強
template
inline
float distance(const t &u, const t &v);
bool cpair2(pointx x, int n, pointx &a, pointx &b, float &d);
template
void mergesort(t a, int n);
template
void mergepass(t x, t y, int s, int n);
template
void merge(t c, t d, int l, int m, int r);
void closest(pointx x, pointy y, pointy z, int l, int r, pointx &a, pointx &b, float &d);
int main()
cpair2(x, n, a, b, d);
cout
<< "min distance: "
<< d
return0;}
//求任意兩點之間的距離
template
inline
float distance(const t &u, const t &v)
//按x座標和y座標排序,並求點對。按y座標排序的點記錄了其原來在排好序之後的x陣列中的位置。
//y陣列主要用於儲存某分界線兩端的點,並使其按y座標的大小進行排列,以便於計算。
bool cpair2(pointx x, int n, pointx &a, pointx &b, float &d)
//用分治法實現的歸併排序演算法,該函式實現將長度為s的兩段序列合併成一段。
template
void mergesort(t a, int n)
}//將相鄰兩段排好序的陣列合併成有序序列。
template
void mergepass(t x, t y, int s, int n)
//若x中還有剩餘,則將剩餘的元素少於2s合併到y中
if (i + s1, n - 1);
else
for (int j = i; j <= n - 1; j++)
y[j] = x[j];
}//將c[l...m]中的元素和c[m+1...r]中的元素合併在d中。
template
void merge(t c, t d, int l, int m, int r)
//求最小點對及距離
void closest(pointx x, pointy y, pointy z, int l, int r, pointx &a, pointx &b, float &d)
//如果3個點,則兩兩計算求最小距離及點對。
if (r - l == 2)
if (d2 <= d3)
else
return;
}//其他情況採用二分法分割成幾段來求
int m = (l + r) / 2;
int f = l, g = m + 1;
//m將l,r分割成兩段,分別求m兩邊的點,並按照y座標的大小排列,放在z陣列中
for (int i = l; i <= r; i++)
if (y[i].p>m)
z[g++] = y[i];
else
z[f++] = y[i];
//求l...m間所有點最小點對及距離
closest(x, z, y, l, m, a, b, d);
float dr;
pointx ar, br;
//求m+1...r間所有點的最小點對及距離
closest(x, z, y, m + 1, r, ar, br, dr);
//求兩邊點中最小點對及距離。
if (dr//將m兩邊的點合併到y陣列中,並按y座標大小排列
merge(z, y, l, m, r);
//取矩形條內的點
int k = l;
for (int i = l; i <= r; i++)
if (fabs(y[m].x - y[i].x)//求矩形條內的點的最小距離及點對,並與前面求得的點距比較,取最小。
for (int i = l; ifor (int j = i + 1; jfloat dp = distance(z[i], z[j]);
if (dp}}
}
分治法求解最近點對問題
問題 設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來作...
分治法求最近點對
1 演算法描述 1.分割 將集合s進行以垂直於x軸的直線l進行平均劃分,並且保證sl和sr中的點數目各為n 2,否則以其他方式劃分s,有可能導致sl和sr中點數目乙個為1,乙個為n 1,不利於演算法效率,要盡量保持樹的平衡性 依次找出這兩部分中的最小點對距離 l和 r,記sl和sr中最小點對距離 m...
分治法求最近點對問題
分治法 1 演算法描述 已知集合s中有n個點,分治法的思想就是將s進行拆分,分為2部分求最近點對。演算法每次 選擇一條垂線l,將s拆分左右兩部分為sl和sr l一般取點集s中所有點的中間點的x座標來劃分,這樣可以保證sl和sr中的點數目各為n 2,否則以其他方式劃分s,有 可能導致sl 和sr中點數...