转 最小凸包算法(Convex Hull)(1)-Graham扫描法 -计算几何-算法导论
生活随笔
收集整理的這篇文章主要介紹了
转 最小凸包算法(Convex Hull)(1)-Graham扫描法 -计算几何-算法导论
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
原文地址:http://blog.csdn.net/suwei19870312/article/details/542281
基本問題:
平面上有n個點p1,p2, ..., pn, 要求求出一個面積最小的凸多邊形,使得這個多邊形包含所有平面上的點。
?
根據算法導論上提供的兩個方法做一些介紹:
算法1:
Graham掃描法
下面直接給出一段偽代碼,方便描述:
GRAHAM-SCAN(Q) {1. 取出所有點鐘y坐標最小的點作為初始點p02. 之后對于所有其他點,以p0為中心,點集中的所有點按關于p0的極角逆時針排序,形成p1,p2,..pn-13. push(p0,S) 4. push(p1,S)5. push(P2.S)for(i: 3->m){ px = nexttoTop(S)py = Top(S) do while (如果(py->pi向量)相對于(px->py向量)是向右走的)pop(S)px = nextotTop(S)py = Top(S)push(pi, S);}return S; }最后S棧中保存了所有凸多邊形的頂點集合
?
下面用圖示表示一下算法的過程:
1.初始化所有的p0,p1,...pn-1
?
2.??p0,p1,p2入棧
??
3. 這時候棧頂元素是p2,次棧頂元素p1, 枚舉p3, 那么可以看出, p2->p3的向量相對于p2->p1的向量是向右走的,所以棧中彈出p2, 壓入p3
?
?4. P4入棧,由于棧頂元素是p3,次棧頂元素是p1, 那么p3->p4向量,相對于p1->p3向量是向左走的,所以壓入p4
?
?
5.由于棧頂元素是p4,次棧頂元素是p3, 那么p4->p5向量,相對于p3->p4向量是向右走的,所以彈出p4,壓入p5
//xiaoxia版 #include <stdio.h> #include <math.h> #include <stdlib.h> typedef struct {double x;double y; }POINT; POINT result[102]; //保存凸包上的點,相當于所說的棧S POINT a[102]; int n,top; double Distance(POINT p1,POINT p2) //兩點間的距離 {return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); } double Multiply(POINT p1,POINT p2,POINT p3) //叉積 { return ((p2.x-p1.x)*(p3.y-p1.y)-(p2.y-p1.y)*(p3.x-p1.x)); } int Compare(const void *p1,const void *p2) //根據p0->p1的極值和p0->p2的極值進行比較,如果極值相同則用距離長度比較 {POINT *p3,*p4;double m;p3=(POINT *)p1; p4=(POINT *)p2; m=Multiply(a[0],*p3,*p4) ;if(m<0) return 1;else if(m==0&&(Distance(a[0],*p3)<Distance(a[0],*p4)))return 1;else return -1; } //尋找凸包的過程,p0,p1,p2..的尋找過程在下面main中進行了 void Tubao() {int i;result[0].x=a[0].x;result[0].y=a[0].y;result[1].x=a[1].x;result[1].y=a[1].y;result[2].x=a[2].x;result[2].y=a[2].y;top=2;for(i=3;i<=n;i++){while(Multiply(result[top-1],result[top],a[i])<=0 && top>2)top--;result[top+1].x=a[i].x;result[top+1].y=a[i].y;top++;} } int main() {int i,p;double px,py,len,temp;while(scanf("%d",&n)!=EOF,n){for(i=0;i<n;i++)scanf("%lf%lf",&a[i].x,&a[i].y);if(n==1){printf("0.00/n");continue;}else if(n==2){printf("%.2lf/n",Distance(a[0],a[1]));continue;}//這里的目的好像是找出y坐標最小的點,之后把他定義為P0 py=-1;for(i=0;i<n;i++){if(py==-1 || a[i].y<py){px=a[i].x;py=a[i].y;p=i;}else if(a[i].y==py && a[i].x<px){px=a[i].x;py=a[i].y;p=i;}}//swap(a[0],a[p])temp=a[0].x;a[0].x=a[p].x;a[p].x=temp;temp=a[0].y;a[0].y=a[p].y;a[p].y=temp;//用叉乘來實現排序的比較 qsort(&a[1],n-1,sizeof(double)*2,Compare);a[n].x=a[0].x;a[n].y=a[0].y;//調用tubao() Tubao();len=0.0;for(i=0;i<top;i++)len=len+Distance(result[i],result[i+1]);printf("%.2lf/n",len);}return 0; }算法學習不斷!
?
轉載于:https://www.cnblogs.com/Jason-Damon/archive/2011/10/14/2211058.html
總結
以上是生活随笔為你收集整理的转 最小凸包算法(Convex Hull)(1)-Graham扫描法 -计算几何-算法导论的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【测试】用例设计思路-六方面
- 下一篇: C# Types Type Membe