小白演算法學習 凸包 graham

2021-08-16 01:53:37 字數 2897 閱讀 2445

一.概念:

凸包(convex hull)是乙個計算幾何(圖形學)中的概念。

在乙個實數向量空間v中,對於給定集合x,所有包含x的凸集的交集s被稱為x的凸包。

x的凸包可以用x內所有點(x1,...xn)的線性組合來構造.

在二維歐幾里得空間中,凸包可想象為一條剛好包著所有點的橡皮圈。

用不嚴謹的話來講,給定二維平面上的點集,凸包就是將最外層的點連線起來構成的凸多邊型,它能包含點集中所有的點。

例子:假設平面上有p0~p12共13個點,過某些點作乙個多邊形,使這個多邊形能把所有點都「包」起來。當這個多邊形是凸多邊形的時候,我們就叫它「凸包」。如下圖: 

二.解法:

graham掃瞄法

時間複雜度:o(n㏒n) 

思路:graham掃瞄的思想是先找到凸包上的乙個點,然後從那個點開始按逆時針方向逐個找凸包上的點,實際上就是進行極角排序,然後對其查詢使用。 

步驟:把所有點放在二維座標系中,則縱座標最小的點一定是凸包上的點,如圖中的p0。

把所有點的座標平移一下,使 p0 作為原點,如上圖。

計算各個點相對於 p0 的幅角 α ,按從小到大的順序對各個點排序。當 α 相同時,距離 p0 比較近的排在前面。例如上圖得到的結果為 p1,p2,p3,p4,p5,p6,p7,p8。我們由幾何知識可以知道,結果中第乙個點 p1 和最後乙個點 p8 一定是凸包上的點。 

(以上是準備步驟,以下開始求凸包)

以上,我們已經知道了凸包上的第乙個點 p0 和第二個點 p1,我們把它們放在棧裡面。現在從步驟3求得的那個結果裡,把 p1 後面的那個點拿出來做當前點,即 p2 。接下來開始找第三個點:

連線p0和棧頂的那個點,得到直線 l 。看當前點是在直線 l 的右邊還是左邊。如果在直線的右邊就執行步驟5;如果在直線上,或者在直線的左邊就執行步驟6。

如果在右邊,則棧頂的那個元素不是凸包上的點,把棧頂元素出棧。執行步驟4。

當前點是凸包上的點,把它壓入棧,執行步驟7。

檢查當前的點 p2 是不是步驟3那個結果的最後乙個元素。是最後乙個元素的話就結束。如果不是的話就把 p2 後面那個點做當前點,返回步驟4。

最後,棧中的元素就是凸包上的點了。 

以下為用graham掃瞄法動態求解的過程: 

下面靜態求解過程

三.模板

#include#include

#include

#include

#include

#define pi 3.1415926535

using

namespace

std;

struct

node

;node vex[

1000];//

存入的所有的點

node stackk[1000];//

凸包中所有的點

intxx,yy;

bool cmp1(node a,node b)//

排序找第乙個點

int cross(node a,node b,node c)//

計算叉積

double dis(node a,node b)//

計算距離

bool cmp2(node a,node b)//

極角排序另一種方法,速度快

bool cmp(node a,node b)//

極角排序

intmain()

if(t==1

) printf(

"%.2f\n

",0.00

);

else

if(t==2

) printf(

"%.2f\n

",dis(vex[0],vex[1

]));

else

double s=0

;

//for(i=1; i<=top; i++)

//輸出凸包上的點

//cout

計算凸包的周長

s+=dis(stackk[i-1

],stackk[i]);

s+=dis(stackk[top],vex[0]);//

最後乙個點和第乙個點之間的距離

/*s+=2*pi*l;

int ans=s+0.5;//四捨五入

printf("%d\n",ans);

*/printf(

"%.2lf\n

",s);}}

}

Graham演算法 凸包問題

graham演算法的思路,大概如下 對平面上的點的集合,從中找到有最小的y座標值的點p,然後根據其它點和p的連線與正x軸所成的角度將平面上的點進行排序,排序後,掃瞄從p開始的有序列表,如果所有的這些點都在凸包上,那麼每三個相繼的點,會組成乙個左旋,從另一方面說,如果相繼的三個點,p1,p2,p3,組...

Graham凸包演算法簡介

凸包真是乙個神奇的演算法。對於平面上的一些點,我們要求凸包上所有的點,可以使用graham演算法 時間複雜度o nlogn 先找到最左下的點,把其他的點按叉積排序。然後維護乙個堆疊,每次利用叉積和棧頂比較判斷當前列舉到的點是否是凸包上的點,是則彈出棧頂元素 具體演算法click here 常熟巨大的...

graham求凸包演算法

問題 點集q的凸包 convex hull 是指乙個最小凸多邊形,滿足q中的點或者在多邊形邊上或者在其內。這個演算法是由數學大師葛立恆graham發明的,他曾經是美國數學學會ams att 首席科學家.see 模板 see include include using namespace std cl...