分治 最近點對問題

2021-10-08 03:52:23 字數 2458 閱讀 3164

利用分治方法的經典問題——最近點對問題(closest pair of points problem)

問題描述

n個點在公共空間中,求出所有點對的歐幾里得距離最小的點對。

問題分析

該題直觀的解決方法便是brute force(暴力求解)。

利用分治思想進行求解。首先分析題目,符合分治法的適用條件,規模越小容易求解,同時具有最優子結構。

分治法求解

分解對所有的點按照x座標(或者y)從小到大排序(排序方法時間複雜度o(nlogn)。

根據下標進行分割,使得點集分為兩個集合。

解決遞迴的尋找兩個集合中的最近點對。

取兩個集合最近點對中的最小值min(disleft,disright) min(dis_, dis_)min(dis left,disright)。

合併最近距離不一定存在於兩個集合中,可能乙個點在集合a,乙個點在集合b,而這兩點間距離小於dis。

2023年,由周玉林、熊鵬榮、朱洪教授提出了平面最近點對的乙個改進演算法,針對preparata-shamos演算法提出的6個點,又證明其實只需要4個點就可以確定最近點對距離,該證明提出2個定理,利用更加準確的半徑畫圈,證明了只要對左半域上的每個點p,檢驗右半域y座標與p最近的至多4個點即可(上下個兩個)。具體證明可以參考《求平面點集最近點對的乙個改進演算法》。

根據以上的優化,可以在合併時,通過檢測與左半域點p的y座標相鄰的2個或者3個,即使用4點或者6點來檢測,一般為了省事,只求與p點y座標上界或者下界右半域連續的6個、4個點即可。

時間複雜度

**實現

struct point

point()

};bool cmp_x(const point & a, const point & b)  // 比較x座標

bool cmp_y(const point & a, const point & b)  // 比較y座標

double distance(const point & a, const point & b)

/** function: 合併,同第三區域最近點距離比較

* param: points 點的集合

*        dis 左右兩邊集合的最近點距離

*        mid x座標排序後,點集合中中間點的索引值

*/double merge(vector& points, double dis, int mid)

sort(right.begin(), right.end(), cmp_y);

for (int i = 0, index; i < left.size(); ++i)  // 遍歷左邊的點集合,與右邊符合條件的計算距離

}return dis;

}double closest(vector& points)

int main()

sort(points.begin(), points.end(), cmp_x);

printf("最近點對值:%lf", closest(points));

return 0;

}

分治 最近點對問題

最近點對問題 在平面內有點集 s s 包含 n 個點。已知每個點的座標 x,y 求最近的兩點之間的距離 n 2 如果存在重合的兩個點,最近距離記為0。列舉的方法時間複雜度是o n 2 通過分治可以將時間複雜度降為o nlog n 利用一條直線將平面上的所有點集 s 分成兩部分s1 s2,分別計算這兩...

最近點對問題 遞迴,分治

問題描述 在二維平面上的n個點中,找出最近的一對點,就是最近點對問題。如下 include include include using namespace std 頂點座標 typedef struct point 操作頂點座標 typedef struct tpoint double d 10e6...

平面最近點對問題 分治

在與聯盟的戰鬥中屢戰屢敗後,帝國撤退到了最後乙個據點。依靠其強大的防禦系統,帝國擊退了聯盟的六波猛烈進攻。經過幾天的苦思冥想,聯盟將軍亞瑟終於注意到帝國防禦系統唯一的弱點就是能源 該系統由n個核電站 能源,其中任何乙個被摧毀都會使防禦系統失效。將軍派出了n個 進入據點之中,打算對能源站展開一次突襲。...