日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

转 最小凸包算法(Convex Hull)(1)-Graham扫描法 -计算几何-算法导论

發(fā)布時(shí)間:2025/3/15 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 转 最小凸包算法(Convex Hull)(1)-Graham扫描法 -计算几何-算法导论 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

原文地址:http://blog.csdn.net/suwei19870312/article/details/542281

基本問(wèn)題:

平面上有n個(gè)點(diǎn)p1,p2, ..., pn, 要求求出一個(gè)面積最小的凸多邊形,使得這個(gè)多邊形包含所有平面上的點(diǎn)。

?

根據(jù)算法導(dǎo)論上提供的兩個(gè)方法做一些介紹:

算法1:

Graham掃描法

下面直接給出一段偽代碼,方便描述:

GRAHAM-SCAN(Q) {1. 取出所有點(diǎn)鐘y坐標(biāo)最小的點(diǎn)作為初始點(diǎn)p02. 之后對(duì)于所有其他點(diǎn),以p0為中心,點(diǎn)集中的所有點(diǎn)按關(guān)于p0的極角逆時(shí)針排序,形成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向量)相對(duì)于(px->py向量)是向右走的)pop(S)px = nextotTop(S)py = Top(S)push(pi, S);}return S; }

最后S棧中保存了所有凸多邊形的頂點(diǎn)集合

?

下面用圖示表示一下算法的過(guò)程:

1.初始化所有的p0,p1,...pn-1

?

2.??p0,p1,p2入棧

??

3. 這時(shí)候棧頂元素是p2,次棧頂元素p1, 枚舉p3, 那么可以看出, p2->p3的向量相對(duì)于p2->p1的向量是向右走的,所以棧中彈出p2, 壓入p3

?

?4. P4入棧,由于棧頂元素是p3,次棧頂元素是p1, 那么p3->p4向量,相對(duì)于p1->p3向量是向左走的,所以壓入p4

?

?

5.由于棧頂元素是p4,次棧頂元素是p3, 那么p4->p5向量,相對(duì)于p3->p4向量是向右走的,所以彈出p4,壓入p5

//xiaoxia版 #include <stdio.h> #include <math.h> #include <stdlib.h> typedef struct {double x;double y; }POINT; POINT result[102]; //保存凸包上的點(diǎn),相當(dāng)于所說(shuō)的棧S POINT a[102]; int n,top; double Distance(POINT p1,POINT p2) //兩點(diǎn)間的距離 {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) //根據(jù)p0->p1的極值和p0->p2的極值進(jìn)行比較,如果極值相同則用距離長(zhǎng)度比較 {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; } //尋找凸包的過(guò)程,p0,p1,p2..的尋找過(guò)程在下面main中進(jìn)行了 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坐標(biāo)最小的點(diǎn),之后把他定義為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;//用叉乘來(lái)實(shí)現(xiàn)排序的比較 qsort(&a[1],n-1,sizeof(double)*2,Compare);a[n].x=a[0].x;a[n].y=a[0].y;//調(diào)用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; }

  算法學(xué)習(xí)不斷!

?

轉(zhuǎn)載于:https://www.cnblogs.com/Jason-Damon/archive/2011/10/14/2211058.html

總結(jié)

以上是生活随笔為你收集整理的转 最小凸包算法(Convex Hull)(1)-Graham扫描法 -计算几何-算法导论的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。