1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
[cpp] view plaincopyprint?
double
MinDistance =
double
.maxvalue;
//设置一个MinDistance存储最近点对的距离,初始值为无穷大
int
PointIndex1,PointIndex2;
//设置PointIndex1,PointIndex2分别存储最近点对的两个点编号
for
(i=1; i< n; i++)
//循环计算n(n-1)/2对点对的距离
{
for
(j=i+1; j<=n; j++)
{
double
PointDistance = Distance(S[i],S[j]);
//求得point i和point j之间的距离
if
PointDistance < MinDistance;
//如果当前点对距离小于最小点对距离,则设置最小点对距离等于当前点对距离
{
MinDistance = PointDistance;
PointIndex1 = i;
PointIndex2 = j;
}
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
1)对点集S的点x坐标和y坐标进行升序排序,获得点集Sx和Sy
2)令δ=∞;
//δ为最小点位距离
3)Divide_conquer(Sx,Sy,δ)
//分治法
if
(Sx.count=1) thenδ=∞;
//如果Sx中只有一个点,则δ=∞
return
δ;
else
if
(Sx.count=2 and d(Sx.[0],Sx.[1])<δ)
//如果Sx中只有2个点,则δ为两点之间距离
δ=d(Sx.[0], Sx.[1]);
return
δ;
else
//如果Sx中多于2个点,则将Sx,Sy分治,以中心点画线,将Sx分为左右两部分SxL和SxR,Sy分为SyL和SyR
j1=1,j2=1,k1=1,k2=1;
mid =Sx.count/2;
//mid为Sx中的中间点点号
L =Sx.[mid].x;
//L为Sx中的中间点x坐标
for
(i=1,i
{
if
(i<=mid)
//将Sx中间线以左地方的点存入到SxL,新数组保持原来的升序性质
SxL[k1] =Sx[i] k1++;
else
//将Sx中间线以右的地方的点存入到SxR,新数组保持原来的升序性质
SxR.count[k2] = Sx[i] k2++;
if
(Sy[i].x
SyL[j1] = Sx[i] j1++;
else
//将Sy中间线以右地方的点存入到SyR,新数组保持原来的升序性质
SyR[j2] = Sx[i] j2++;
}
δL = Divide_conquer(SxL,SyL,δ);
//获取Sx中的的最小点位距离δL
δR = Divide_conquer(SxR,SyR,δ);
//获取Sy中的的最小点位距离δR
δ= min (δL,δR);
δ=merge(SyL,SyR,δ);
//获Sx中Sy交界处的最小点位距离,并综合 δL和δR 求出点集的最小点位距离δ
return
δ;
函数merge(SyL,SyR,δ)
merge(SyL,SyR,δ)
{
i1=1,i2=1;
for
(i=1,i
{
if
(SyL[i].x>L-δ)
then S'yL[i1]= SyL[i], i1++,
}
for
(i=1,i
{
if
(SyR[i].x
then S'yR[i2]= SyR[i], i2++,
}
t=1;
for
(i=1,i
{
while
(S
'yR[t].y< S'
yL[t].y and t < SyR.count)
//获取点集S'yR内距离点S'yL[t]y坐标最接近的点号
{ t++; }
for
( j= max(1,t-3), j<=min(t+3,S
'yR.count),j++) //计算S'
yR中的点与S'yL[t]y坐标相邻的六个点的距离
{
if
(d(S
'yL[i],S'
yL[j])<δ)
//如果前两点之间距离小于δ
then δ = d(S
'yL[i],S'
yL[j]);
//则最小点位距离δ为当前两点之间距离
}
return
δ
}
|