最小覆蓋圓

2021-10-21 19:48:58 字數 2606 閱讀 3344

最小覆蓋圓解決的問題模板大概是:

在乙個平面內的很多點中,找出乙個最小的圓,使之覆蓋所有的點。

假設點的個數為 n

nn, 最小覆蓋圓面積為 rrr。

當 n =1

n = 1

n=1 時,毋庸置疑,此時 r=0

r = 0

r=0;

當 n =2

n = 2

n=2 時,此時r應該為 r=d

is(p

oint

1,po

int2

)/2r = dis(point1, point2) / 2

r=dis(

poin

t1,p

oint

2)/2

當 n =3

n = 3

n=3 時,那麼 r

rr 就是三個點形成的最小圓,也就是三個點形成的三角形的外接圓。

那麼 n

>

3n > 3

n>

3 時呢?我們可以延續剛剛的思路

因為在取點的時候,可能第一次或者之後取的兩個點三個點做出的圓就包含了所有點, 導致所求圓面積不是最小的,所以在計算之前需要把取點的順序打亂,也就是random一下。

由於只需要三個點就可以確定乙個圓了,其圓心就是三角形的外接圓圓心(兩個點的話那就兩點中點。。),那麼我們來模擬一下過程:

① 首先,將所有點隨機排列,使用random_shuffle() 函式。

② 設此時的最小圓圓心為o0,半徑為r0。在點中取出一點 i

ii,若i在圓o0內,則遍歷下乙個點,否則就將其作為當前圓的圓心,r=0

r = 0

r=0,就是 n=1

n = 1

n=1的情況,因為我們需要構造新的圓,使之完全包括前i個點,有乙個點i了,那就還需要再找兩個。

③ 再依次取出i之前的點,作為第二個點j,如果沒有乙個是在r的外面的話就表示當前點i之前的所有的點都在我們之前計算的最小圓中,再進行下去就沒有意義,所以我們需要遍歷下乙個i點,繼續重複我們的計算,也就是i++,然後回到②。每當遇到乙個不在r中的點,這時的 r=d

is(i

,j)/

2r = dis(i, j) / 2

r=dis(

i,j)

/2,就是 n=2

n = 2

n=2 的情況,然後就進行下一步。

④ 依次取出j之前的所有點, 作為第三個點k,同樣地,如果沒有乙個點在當前我們計算的最小圓的外面,那麼再進行下去也沒有意義,就需要遍歷下乙個點j,也就是 j++

j ++

j++ ,然後回到③。每當遇到乙個不在r中的點,就相當於找到了第三個點,這三個點都剛好不在我們最初計算的圓o0中,而且剛好能做出乙個圓剛剛好包含點1~k的圓且,點i、j也都在這個圓的邊界上。

那麼 k+1

j−1k + 1 ~ j - 1

k+1j−1

之間的點呢?所以我們需要繼續重複次步驟,也就是把j之前的所有點都當作一次第三個點,從而計算出能剛剛好包含前 j−1

j - 1

j−1 個點的圓同理,②、③的回溯也是這個原因,這樣一直計算到i == n的話,求出的圓就是能包含n個點的最小圓了。

所以此處只需要三重迴圈,再加三個判斷就能計算了,額這個演算法的時間複雜度。其實只有 o(n

)o(n)

o(n)

啦,算一下。

tips:

求三角形的外接圓,可以用直線方程、也可以運用引數方程,從而求得兩條直線的中垂線,其焦點即為圓心。也可以運用向量的思想求得。

實現模板:

#include

using

namespace std;

typedef

long

long ll;

const

int maxn =

1e3+10;

const

double eds =

1e-12

;struct nodenode[maxn]

;// 點

double r =0;

//半徑

doublesq(

double x)

double

dis(

double x1,

double y1,

double x2,

double y2)

intmain()

random_shuffle

(node, node + n)

;//將點隨機排列,防止好心人教你wa題

double r = node[0]

.x, l = node[0]

.y;//圓心的橫、縱座標

double x1, x2, x3, y1, y2;

for(int i =

1; i < n; i ++)}

}}}}

cout << r *

2.0<<

"\n"

;return0;

}

最小覆蓋圓的增量演算法

題意 給出平面上的一些點,要求用乙個最小的圓,把所有的點包圍起來。最小覆蓋圓,增量法 假設圓o是前i 1個點得最小覆蓋圓,加入第i個點,如果在圓內或邊上則什麼也不做。否,新得到的最小覆蓋圓肯定經過第i個點。然後以第i個點為基礎 半徑為0 重複以上過程依次加入第j個點,若第j個點在圓外,則最小覆蓋圓必...

hdu3007 最小覆蓋圓問題

題目 buried memory 最小圓覆蓋,很經典的問題。題目大概是,平面上n個點,求乙個半徑最小的圓,能夠覆蓋所有的點。如果要求乙個最小覆蓋圓,這個圓至少要由三個點確定。有一種演算法就是任意取三個點作圓,然後判斷距離圓心最遠的點是否在圓 內,若在,則完成 若不在則用最遠點更新這個圓。這裡不仔細介...

凸包和最小覆蓋圓問題

給出平面上的一些點,求覆蓋這些點的最小圓。具體問題可以見hdu 2215。具體解法是,先求凸包,然後列舉凸包上任意3個點,若列舉的三個點構成鈍角三角形,則最大半徑為最長邊的一半 否則,半徑r a b c 4 s 其中s是面積,具體面積可以用叉乘求得,s 向量a叉乘向量b 的絕對值的一半。view c...