分治法求平面最近點對入門

2021-09-23 06:08:50 字數 2556 閱讀 3257

一.平面最近點對問題.

平面最近點對:在乙個平面上有n

nn個點,求出距離最近的兩個點.

平面最近點對是計算幾何中乙個十分經典且基礎的問題,通常採用分治法來解決.

二.直線最近點對的分治法.

在用分治法解決平面最近點對之前,我們用分治法來解決一下直線最近點對問題.

考慮在一條直線上暴力列舉兩個點並計算距離取最小,很明先複雜度是o(n

2)o(n^2)

o(n2

)的,比較慢.

於是我們考慮先給n

nn的個點按照座標排序,然後分治,每次分成左右兩段;然後合併回去,每次大區間的答案為兩個小區間的答案和左區間最右邊的點與右區間最左邊的點的距離的最小值.

容易發現這個演算法的時間複雜度為o(n

)o(n)

o(n)

,但由於排序複雜度為o(n

log⁡n)

o(n\log n)

o(nlogn)

.當然這個問題有乙個更簡單的做法——直接大力排序後將第i

ii個點和第i+1

i+1i+

1個點的距離取最小值.

三.平面最近點對的分治法.

我們考慮一下如何把一維的分治法拓展到二維上.

考慮仍然按照橫座標x

xx排序,然後每次通過中位數分成兩組,遞迴後答案合併上來.

合併的過程可以通過兩個小區間的答案與大力列舉乙個點在左區間另乙個點在右區間的距離取最小值…等等大力列舉不是o(n

2)o(n^2)

o(n2

)的麼…

這怎麼辦呢?能不能優化一下呢?

考慮每一次先求出左區間和右區間的答案的最小值d

dd,很明顯跨界的兩個點的橫座標與分治中心不應該超過ddd.

那麼先把所有橫座標與分治中心不超過d

dd的所有點提取出來,接下來我們只考慮這些點.

考慮把這些點按照縱座標y

yy排序,然後大力列舉每乙個點並再列舉這個點後面的點取最小值.容易發現後面的點與這個點的縱座標之差大於d

dd就肯定可以退出了,直接break掉.

這樣子做貌似還是o(n

2)o(n^2)

o(n2

)才能合併,但事實上這樣子是o(n

log⁡2n

)o(n\log^2n)

o(nlog2n

)的演算法,下面我們將會分析時間複雜度.

四.分治法的時間複雜度.

很容易發現這個分治法複雜度的關鍵在於合併過程,而合併過程的複雜度瓶頸在於乙個點最多可以有多少個候選點.

我們觀察乙個藍色點的候選點,發現藍點的候選點必然在它下面的由兩個邊長為d

dd的正方形組成的長方形中.

考慮對於這個長方形,它最多會被當前我們選的中點所在的平行於y

yy軸的直線分成兩半,由於每一半中任意兩個點的距離至少為d

dd,所以長方形中所有的點的數量是乙個常數,經過計算長方形中所有點的數量上限為666.

那麼很明顯這個合併演算法的複雜度就只有o(6

n)o(6n)

o(6n

)了,那麼總複雜度就是o(n

log⁡2n

)o(n\log^2n)

o(nlog2n

)的.五.例題與**.

例題:luogu1429.

**如下:

#include

using namespace std;

#define abigail inline void

typedef

long

long ll;

const

int n=

200000

;const

double inf=

1e200

;int n;

struct pointd[n+9]

,t[n+9]

;bool cmp1

(const point &a,

const point &b)

bool cmp2

(const point &a,

const point &b)

double

sqr(

double x)

double

get_dis

(point a,point b)

double

divide

(point *d,

int l,

int r)

double

solve

(point *d,

int n)

abigail into()

abigail outo()

intmain()

分治法求最近點對

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

分治法求最近點對問題

1 演算法描述 已知集合s中有n個點,分治法的思想就是將s進行拆分,分為2部分求最近點對。演算法每次 選擇一條垂線l,將s拆分左右兩部分為sl和sr,l一般取點集s中所有點的中間點的x座標來劃分,這樣可以保證sl和sr中的點數目各為n 2,否則以其他方式劃分s,有 可能導致sl 和sr中點數目乙個為...