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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

算法设计与分析——递归与分治策略——最接近点对问题

發布時間:2023/12/4 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法设计与分析——递归与分治策略——最接近点对问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【問題描述】
最近對問題要求在包含有n個點的集合S中,找出距離最近的兩個點。設 p1(x1,y1),p2(x2,y2),……,pn(xn,yn)是平面的n個點。

嚴格地將,最近點對可能不止一對,此例輸出一對即可。

【基本算法思想】
暴力法:
在蠻力法實現最近點對問題中,將問題簡化:距離最近的點對可能多于一對,找出一對即可,另外只考慮二維平面中的情況。此處考慮到
直接用公式計算其距離(歐幾里得距離):

通過遍歷所有點集,計算出每一個點對的距離,計算出最近的距離并輸出。避免同一對點計算兩次,只考慮i<j的點對(pi,pj)。
其主要循環的步驟就是求出平方值,執行的次數為:

分治法:
在利用分治法思想解決此問題時,首先考慮將最近對問題進行分治,設計其分治策略。將集合S分成兩個子集S1和S2,根據
平衡子問題原則,每個子集中的點數大致都為n/2。這樣分治后,最近點對將會出現三種情況:在S1中,在S2中或者最近
點對分別在集合S1和S2中。利用遞歸分析法分別計算前兩種情況,第三種方法另外分析。求解出三類子情況后,
再合并三類情況,比較分析后輸出三者中最小的距離。

復雜度分析: 在分治算法中,當求解n個點的集合的最近點對時,對于上述三類情況中的前兩者可由遞歸算得,
而分析可得第三類情況的時間代價 ,合并后問題求解的總的時間按復雜度可由下列公式來:

//分治法求解最近點對問題(C++) #include<stdio.h> #include<math.h> #include<string.h> #include<algorithm> #include<iostream> using namespace std; struct point{ //點結構double x,y; }; double Distance(point a,point b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } bool cmp(point a,point b){ //按y升排序輔助函數return a.y<b.y; } bool cmp2(point a,point b){ //按x升排序輔助函數return a.x<b.x; } double closestPoint(point s[],int low,int high,point rec[]){double d1,d2,d3,d;int mid,i,j,index;double x1,y1,x2,y2; //記錄點對的位置point P[high-low+1],temp1[2],temp2[2],temp3[2]; //輔助空間if(high-low==1){ //兩個點的情況rec[0].x=s[low].x;rec[0].y=s[low].y;rec[1].x=s[high].x;rec[1].y=s[high].y;return Distance(s[low],s[high]);}if(high-low==2){ //三個點的情況d1=Distance(s[low],s[low+1]);d2=Distance(s[low+1],s[high]);d3=Distance(s[low],s[high]);if((d1<d2)&&(d1<d3)){rec[0].x=s[low].x;rec[0].y=s[low].y;rec[1].x=s[low+1].x;rec[1].y=s[low+1].y;return d1;}else if(d2<d3){rec[0].x=s[low+1].x;rec[0].y=s[low+1].y;rec[1].x=s[high].x;rec[1].y=s[high].y;return d2;}else {rec[0].x=s[low].x;rec[0].y=s[low].y;rec[1].x=s[high].x;rec[1].y=s[high].y;return d3;}}mid=(low+high)/2; //其他情況遞歸d1=closestPoint(s,low,mid,rec);temp1[0]=rec[0];temp1[1]=rec[1];d2=closestPoint(s,mid+1,high,rec);temp2[0]=rec[0];temp2[1]=rec[1];if(d1<d2){d=d1;rec[0]=temp1[0];rec[1]=temp1[1];}else {d=d2;rec[0]=temp2[0];rec[1]=temp2[1];}index=0;for(i=mid;(i>=low)&&((s[mid].x-s[i].x)<d);i--) //點集合p1P[index++]=s[i];for(i=mid+1;(i<=high)&&((s[i].x-s[mid].x)<d);i++) //點集合p2P[index++]=s[i];sort(P,P+index,cmp); //升序排列for(i=0;i<index;i++){for(j=j+1;j<index;i++){if((P[j].y-P[i].y)>=d)break;else {d3=Distance(P[i],P[j]);if(d3<d){rec[0].x=P[i].x;rec[0].y=P[i].y;rec[1].x=P[j].x;rec[1].y=P[j].y;d=d3;}}}}return d; } int main(){point p[10]; //設定點的集合int n;double minDist;cout<<"輸入點的個數:\n"; //輸入點的個數cin>>n;cout<<"輸入點集:(x,y)\n";for(int i=0;i<n;i++)cin>>p[i].x>>p[i].y;sort(p,p+n,cmp2); //對輸入的點先排序point index[2];minDist=closestPoint(p,0,n-1,index);cout<<"最小距離點對為:("<<index[0].x<<","<<index[0].y<<"),("<<index[1].x<<","<<index[1].y<<")\n";cout<<"最小距離為:\n"<<minDist; //輸出點對的最小問題return 0; }

————————————————
版權聲明:本文為CSDN博主「fanleehao」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_28666193/article/details/53351482

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的算法设计与分析——递归与分治策略——最接近点对问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。