算法设计与分析第五次作业

实验报告

课程名称 《算法分析与设计》 实验日期 2021年 4 月 12 日 至 2021 年 4 月 15 日
学生姓名 郑超逸 所在班级 计算机195 学号 2019211909055
实验名称 最近对问题
实验地点 勤园13-208 同组人员 无

1.问题
首先来看最近对问题,最近对问题描述的就是在包含n个端的集合中找到距离最近的两个点,当然问题也可以定义在多维空间中,但是这里只是跟随书上的思路实现了二维情况下的最近对问题。假设所有讨论的点是以标准的笛卡尔坐标形式(x,y)给出的,那么在两个点Pi=(Xi,Yi)和Pj=(Xj,Yj)之间的距离是标准的欧几里得距离: d(Pi,Pj)=sqrt( (X1-X2)2+(Y1-Y2)2 )
2.解析
一是:怎么表示一个点集,因为最终返回的下标是集合中点的下标,要用的数据结构就是一维数组,但是点的xy坐标又要怎么表示呢,使用 struct类型的点结构,该结构拥有的成员变量就是x代表的横坐标和y代表的纵坐标,这样就可以直接创建该结构的一位数组进行计算了。

二是:BruteForceClosetPoints(P)函数返回的是两个最近对下标的值,但是用return只能返回一个值,因此这里在BruteForceClosetPoints函数的参数表中增加了引用类型的变量  &index1,&index2。

三是:在计算点间距离前,需要将最大值付给存储当前最小距离的变量dmin

上述为蛮力算法

分治策略:
P为笛卡尔平面上n>1个点构成的集合。且按X轴坐标升序排列。

当2≤n≤3时,问题就可以通过蛮力算法求解。
当n>3时,可以利用点集在x轴方向上的中位数m,在该处作一条垂线,将点集分成大小分别为[n/2] 和[n/2]的来给两个子集P1和Pr。得其中[n/2]个点在线的左边或线上,另外的[n/2]个点在线的右边或线上。然后通过递归求解子问题P1和Pr来得到最近点对问题的解。其中d1和dr分别表示在P1和Pr中的最近对距离,并定义d=min{d1,dr}。
3.设计
算法:BruteForceCloestPoints§
//使用蛮力算法求平面中距离最近的两点
//输入;一个n(n≥2)个点的列表p,p1 = (x1, y1),…,pn = (xn, yn)
//输出:两个最近点的问题

d ← ∞
for i ← 1 to n-1 do
for j ← i+1 to n do
d ← min(d, sqrt((xi – xj)2+(yi – yj)2))//sqrt是平方根函数
return d

算法:EfficientClosestPair(P,Q)
//使用分治算法来求解最近点对问题
//输入:数组P中存储了平面上的n≥2个点,并且按照这些点的x轴坐标升序排列
// 数组Q存储了与P相同的点,知识它是按照这点的y轴坐标升序排列
//输出:最近点对之间的欧几里得距离
if n≤3
返回由蛮力算法求出的最小距离
else
将P的前[n/2]个点复制到P1
将Q的前[n/2]个点复制到Q1
将P中余下的[n/2]个点复制到P1
将Q中余下的[n/2]个点复制到Q1
d1←EfficientCloestPair(P1,Q1)
dr←EfficientCloestPair(Pr,Qr)
d←min{d1,dr}
m←P[[n/2]-1].x
将Q中所有|x-m| < d 的点复制到数组S[0…num-1]
dminsq← d2
for i←0 to num-2 do
k← i+1
while k≤num-1 and (S[k].y-S[i].y)2 小于 dminsq
dminsq←min((S[k].x – S[i].x)2+(S[k].y-S[i].y)2, dminsq)
k← k+1
return sqrt(dminsq)
4.分析
合并的复杂度O(n),分治递归的复杂度O(n/2)

总时间复杂度O(nlogn)
5.源码
https://github.com/Lin02993/Algorithm-Analysis-and-Practice-on-the-job

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值