算法笔记分治法最接近点对问题_精品文档Word格式文档下载.docx
- 文档编号:14437000
- 上传时间:2022-10-22
- 格式:DOCX
- 页数:18
- 大小:131.39KB
算法笔记分治法最接近点对问题_精品文档Word格式文档下载.docx
《算法笔记分治法最接近点对问题_精品文档Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《算法笔记分治法最接近点对问题_精品文档Word格式文档下载.docx(18页珍藏版)》请在冰豆网上搜索。
然而这种方法无法直接推广到二维的情形。
因此,对这种一维的简单情形,我们还是尝试用分治法来求解,并希望能推广到二维的情形。
假设我们用x轴上某个点m将S划分为2个子集S1和S2,使得S1={x∈S|x≤m};
S2={x∈S|x>
m}。
这样一来,对于所有p∈S1和q∈S2有p<
q。
递归地在S1和S2上找出其最接近点对{p1,p2}和{q1,q2},并设d=min{|p1-p2|,|q1-q2|},S中的最接近点对或者是{p1,p2},或者是{q1,q2},或者是某个{p3,q3},其中p3∈S1且q3∈S2。
如图所示。
如果S的最接近点对是{p3,q3},即|p3-q3|<
d,则p3和q3两者与m的距离不超过d,即|p3-m|<
d,|q3-m|<
d,也就是说,p3∈(m-d,m],q3∈(m,m+d]。
由于在S1中,每个长度为d的半闭区间至多包含一个点(否则必有两点距离小于d),并且m是S1和S2的分割点,因此(m-d,m]中至多包含S中的一个点。
同理,(m,m+d]中也至多包含S中的一个点。
由图可以看出,如果(m-d,m]中有S中的点,则此点就是S1中最大点。
同理,如果(m,m+d]中有S中的点,则此点就是S2中最小点。
因此,我们用线性时间就能找到区间(m-d,m]和(m,m+d]中所有点,即p3和q3。
从而我们用线性时间就可以将S1的解和S2的解合并成为S的解。
也就是说,按这种分治策略,合并步可在O(n)时间内完成。
这样是否就可以得到一个有效的算法了呢?
还有一个问题需要认真考虑,即分割点m的选取,及S1和S2的划分。
选取分割点m的一个基本要求是由此导出集合S的一个线性分割,即S=S1∪S2
,S1∩S2=Φ,且S1={x|x≤m};
S2={x|x>
容易看出,如果选取m=[max(S)+min(S)]/2,可以满足线性分割的要求。
选取分割点后,再用O(n)时间即可将S划分成S1={x∈S|x≤m}和S2={x∈S|x>
然而,这样选取分割点m,有可能造成划分出的子集S1和S2的不平衡。
例如在最坏情况下,|S1|=1,|S2|=n-1,由此产生的分治法在最坏情况下所需的计算时间T(n)应满足递归方程:
T(n)=T(n-1)+O(n)
它的解是T(n)=O(n^2)。
这种效率降低的现象可以通过分治法中“平衡子问题”的方法加以解决。
即通过适当选择分割点m,使S1和S2中有大致相等个数的点。
自然地,我们会想到用S的n个点的坐标的中位数来作分割点。
在选择算法中介绍的选取中位数的线性时间算法使我们可以在O(n)时间内确定一个平衡的分割点m。
本程序确定平衡点采用m=[max(S)+min(S)]/2方法。
如果需要利用中位数作分割点,看结合笔者博文《0005算法笔记——线性时间选择》改写。
一维最接近临近点对问题程序清单如下:
[cpp]
viewplain
copy
1.//2d10-1
一维最邻近点对问题
2.#include
"
stdafx.h"
3.#include
<
ctime>
4.#include
iostream>
5.using
namespace
std;
6.
7.const
int
L=100;
8.//点对结构体
9.struct
Pair
10.{
11.
float
d;
//点对距离
12.
d1,d2;
//点对坐标
13.};
14.float
Random();
15.int
input(float
s[]);
//构造S
16.float
Max(float
s[],int
p,int
q);
17.float
Min(float
18.template
class
Type>
19.void
Swap(Type
&
x,Type
y);
20.template
21.int
Partition(Type
s[],Type
x,int
l,int
r);
22.Pair
Cpair(float
23.
24.int
main()
25.{
26.
srand((unsigned)time(NULL));
27.
m;
28.
s[L];
29.
30.
m=input(s);
31.
d=Cpair(s,0,m-1);
32.
cout<
endl<
最近点对坐标为:
(d1:
d.d1<
d2:
d.d2<
)"
;
33.
这两点距离为:
d.d<
endl;
34.
return
0;
35.}
36.
37.
38.float
Random()
39.{
40.
result=rand()%10000;
41.
result*0.01;
42.}
43.
44.int
s[])
45.{
46.
length;
47.
输入点的数目:
48.
cin>
>
49.
点集在X轴上坐标为:
50.
for(int
i=0;
i<
i++)
51.
{
52.
s[i]=Random();
53.
s[i]<
54.
}
55.
56.
57.}
58.
59.
60.float
r)//返回s[]中的最大值
61.{
62.
s_max=s[l];
63.
i=l+1;
=r;
64.
if(s_max<
s[i])
65.
s_max=s[i];
66.
s_max;
67.}
68.
69.float
r)//返回s[]中的最小值
70.{
71.
s_min=s[l];
72.
73.
if(s_min>
74.
s_min=s[i];
75.
s_min;
76.}
77.
78.template
79.void
y)
80.{
81.
Type
temp
=
x;
82.
x
y;
83.
y
temp;
84.}
85.
86.template
87.int
r)
88.{
89.
i
l
-
1,j
r
+
1;
90.
91.
while(true)
92.
93.
while(s[++i]<
94.
while(s[--j]>
x);
95.
if(i>
=j)
96.
97.
break;
98.
99.
Swap(s[i],s[j]);
100.
101.
j;
102.}
103.
104.//返回s[]中的具有最近距离的点对及其距离
105.Pair
106.{
107.
min_d={99999,0,0};
//最短距离
108.
109.
if(r-l<
1)
min_d;
110.
m1=Max(s,l,r),m2=Min(s,l,r);
111.
112.
m=(m1+m2)/2;
//找出点集中的中位数
113.
114.
//将点集中的各元素按与m的大小关系分组
115.
j
Partition(s,m,l,r);
116.
117.
P
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 笔记 分治 最接近 问题 精品 文档