1. 程式人生 > >最小圓覆蓋(經典演算法【三點定圓)

最小圓覆蓋(經典演算法【三點定圓)

剛剛學了一些基礎的三維計算幾何
接觸到了增量法——一種看似暴力,實際睿智的演算法
下面就是增量法在另一類問題上的展現

演算法原文

問題描述

給定n個點,用一個最小的圓把這些點全部覆蓋,求這個圓的圓心半徑

演算法

① 將所有點隨機排布(這樣可以保證演算法的複雜度)

② 初始隨意找到兩點,設為P1,P2,以P1P2為直徑得到初始圓,設為C2Ci表示包含前i個點的最小圓)

③ 按順序依次加點,設當前點為Pi:若Pi在當前圓Ci1內,Ci=Ci1;否則進入④

④ 一旦進入④,就說明我們需要在構造一個新的圓
顯然插入點

Pi一定在新圓的邊界上
簡單的,我們直接以P1Pi為直徑暫且得到一個Ci

⑤ 新得到的Ci不一定能包含1~i所有的點
我們找到不在Ci中的一點Pj(j<i),那麼Pi,Pj一定在更新的圓的邊界上
現在為止,我們能確定有兩個點(Pi,Pj)在更新的圓的邊界上
因此,簡單的,我們直接以P1Pj為直徑暫且得到一個Cj

⑥ 同樣的,新得到的Cj不一定能包含1~j所有的點
我們找到不在Cj中的一點Pk(k<j<i),那麼Pi,Pj,Pk一定在更新的圓的邊界上

現在我們能確定有三個點(Pi,PjPk)在更新的圓的邊界上
因為三點確定一個圓,Pi,PjPk構成了新的圓,一定能覆蓋前i個點

這裡寫圖片描述
上圖中展示的就是一個簡單維護過程

於是,這個問題就被轉化為若干個子問題來求解了

由於三個點確定一個圓,我們的過程大致上做的是從沒有確定點,到有一個確定點,再到有兩個確定點,再到有三個確定點來求圓的工作

時間複雜度:O(N)

空間複雜度:O(N)

這裡寫圖片描述

小細節

Q1.

過三點如何求圓?

A1.

先求叉積

若叉積為0,即三個點在同一直線,那麼找到距離最遠的一對點,以它們的連線為直徑做圓即可;

若叉積不為0,即三個點不共線,那麼就求三角形的外接圓

Q2.

如何求三角形外接圓?

A1.

設三個點(x1,y1),(x2,y2),(x3,y3)
設過(x1,y1),(x2,y2)的直線l1方程為Ax+By=C
它的中點為