生活随笔
收集整理的這篇文章主要介紹了
算法设计与分析——递归与分治策略——最接近点对问题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【問題描述】
最近對問題要求在包含有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個點的集合的最近點對時,對于上述三類情況中的前兩者可由遞歸算得,
而分析可得第三類情況的時間代價 ,合并后問題求解的總的時間按復雜度可由下列公式來:
#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
){ return a
.y
<b
.y
;
}
bool cmp2(point a
,point b
){ 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
--) P
[index
++]=s
[i
];for(i
=mid
+1;(i
<=high
)&&((s
[i
].x
-s
[mid
].x
)<d
);i
++) P
[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
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
以上是生活随笔為你收集整理的算法设计与分析——递归与分治策略——最接近点对问题的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。