分治法求解最近點距

2021-07-11 03:34:39 字數 2877 閱讀 9117

最近點對問題很簡單,就是給定一堆點(這裡是二位座標下),求解最近的點的距離,該問題可以用窮舉法求解,雙重迴圈就夠了,就不說了,主要看一下分治法的**,**也很簡單,有注釋。

**如下:

採用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中點數...