求一個點集的最大空心圓,用基本的枚舉可以很容易想到O(n^4)的方法,但是由於計算幾何進階演算法Voronoi圖的存在,求最大空心圓的複雜度只需要O(n*logn)
Voronoi圖是很複雜的東東,不過我和它還挺有緣的,第一次見面是在高二,《金牌之路——高中電腦競賽解題指導》上面看到的,由於對幾何的熱愛當時還真學了,後來才知道這麼偏僻的演算法幾乎不會考。昨晚複習了一晚上,也只是掌握了一種用雙向迴圈鏈表維護Voronoi多邊形的方法、估計是一種比較基本的方法。
Voronoi圖的定義:
1.設p,q是平面上的兩個點,L是pq的中垂線,L將平面分為兩個部分【L左】和【L右】,在【L】左內的點r有特性|pr|<|qr|,即位於【L左】內的點比平面其他點更接近p,不妨記H(p,q)=【L左】,同理H(q,p)=【L右】
2.給定平面上n個點的點集S={p1,p2,……pn}。定義V(pi)是所有j(i!=j)的H(pi,pj)的交集,即V(pi)表示比其他點更接近於pi的電的軌跡是n-1個半平面的交,這是一個不多於n-1條邊的凸多邊形地區,稱為關聯於pi的Voronoi多邊形(域)
Voronoi圖的特點:
1.Vor(S)把平面劃分成n個多邊形域,每個多邊形域V(pi)包含且只包含S的一個點pi。
2.Vor(S)的邊是S中某對點的中垂線的一個線段或者射線。
3.V(pi)是無界的,若且唯若pi屬於凸包外界的點集。
4.Voronoi圖至多有2*n-5個頂點和3*n-6條邊。
5.每個Voronoi點恰好是三條Voronoi邊的交點(假如任何四點都不共圓的話)。也就是說Voronoi點就是形成三邊的三點的外界圓圓心,而且所有的這些外界圓有個特點:各自內部不含任何S點集的點(空心圓)。
利用第5條性質就可以線性掃描Voronoi圖,解決最大空心圓問題。
Voronoi圖在計算幾何裡的實現一般是用雙向迴圈鏈表維護Voronoi圖的有向邊;產生時候利用分治思想,不過內部超級複雜,要求正切線(複雜度O(n)),構造穿梭的折線確定相交的邊,刪除釋放、合并。有一種很巧妙的構造折線的方法(三角形頂點轉移法)有利於降低代碼編寫難度。