最近对问题-算法分析与实践作业5

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(p)
//使用蛮力算法求平面中距离最近的两点
//输入;一个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)

实验截图:
在这里插入图片描述

出了点问题截图:
在这里插入图片描述
当我把个数变大的时候,因为我用了随机数生成点,然后因为递减,然后x的平方+y的平方跌破了double数值的下限最后编译器做处理,然后以边界大小处理。最后就会出现两个点一样的情况

解决办法:可以手动输入改变点的值。

4. 分析

在这里插入图片描述

5. 源代码地址

https://github.com/Lin02993/Algorithm-Analysis-and-Practice-on-the-job

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值