当前位置:首页 » 操作系统 » 距离最短算法

距离最短算法

发布时间: 2024-11-23 17:19:08

算法 | 常用距离算法详解


算法详解:常用距离算法解析


在计算空间中两点之间的距离时,除了常规的直线距离,还有几种重要的距离算法,包括欧氏距离、曼哈顿距离和切比雪夫距离。这些距离各有特点,适用于不同的场景。下面逐一介绍它们的定义、公式以及应用场景。


1. 欧氏距离

在二维和三维空间中,欧氏距离是最直观的,由两点坐标 [x1, y1] 和 [x2, y2] 计算,公式为 sqrt((x2-x1)^2 + (y2-y1)^2)。例如,点 A(1,2) 和 B(3,4) 的欧氏距离为 sqrt((3-1)^2 + (4-2)^2)。三维空间中的公式同样适用。欧氏距离常用于测量实际空间中的距离,但计算时可能受浮点数精度影响。


2. 曼哈顿距离

曼哈顿距离在棋盘格中表现明显,为两点横纵坐标的绝对值之和。例如,A(1,1) 和 B(3,4) 的曼哈顿距离为 |3-1| + |4-1|。它有非负性、统一性、对称性和三角不等性等特性。在网格图中,曼哈顿距离代表最短路径。


3. 切比雪夫距离

切比雪夫距离取两点横纵坐标的绝对值的最大值。例如,A(1,1) 和 B(3,4) 的切比雪夫距离为 max(|3-1|, |4-1|)。在国际象棋中,国王与王后的移动距离即为切比雪夫距离。在点只能到达特定邻居的网格图中,也是切比雪夫距离的体现。


转换与应用

曼哈顿距离与切比雪夫距离之间存在联系,通过坐标系变换可以相互转化。在某些问题中,巧妙地将距离类型转换能简化计算。例如,将切比雪夫距离问题转化为曼哈顿距离,便于求解。


以上三种距离算法在编程题中常见,如 [Luogu]P3958 和 P5098。通过理解和掌握它们,你可以在实际问题中灵活运用。


Ⅱ dijkstra算法

Dijkstra算法,一种由荷兰科学家E.W.Dijkstra于1959年发明的寻路算法,被誉为最短路径求解的首选方法,优化后的复杂度可达O((m+n)log(m))。然而,其不兼容负权边问题。

所谓负权边,即边的权重为负值,可以理解为在路径中遇到这种边后,实际成本会降低。例如,一条从A点到B点的边,权重为-1,表示通过这条边,从A点到B点的实际花费会减少1。

算法的关键步骤是松弛操作,其核心原则是依据“三角形两边之和大于第三边”定律,更新两点间的最短路径。具体操作为,对于每条边e(v,w),将源点s到w的距离更新为源点s到v的距离加上v到w的距离的较小值。这样,算法不断调整路径选择,以确保找到从源点s到任一顶点w的最短路径。

算法执行流程可直观理解为从起点出发,逐步扩展其可达范围,不断寻找距离最短的未访问顶点。以A点作为起点,首先访问A点,然后寻找与A相邻未访问的顶点B、D,计算它们到A点的距离。接着,将距离最短的顶点D加入已访问集合S中,并从D出发继续扩展可达范围,寻找未访问的邻居顶点B、C、E,计算它们到A点的距离。在D的邻居中,B和D到A点的距离相同,都加入结果集。然后,从B或C出发,但由于B已无未访问邻居,转向C,寻找其未访问邻居E,并将E加入结果集中。

通过使用链式前向星与BFS实现该算法,BFS在循环中将所有邻居放在一起比较到源点的距离,需要额外的排序步骤,例如优先队列来优化。

对于无权图,最短路径定义为经过边数最少的路径。若不熟悉链式前向星,使用边集数组表示图也十分简便。

Ⅲ 最短路径算法

Dijkstra算法,A*算法和D*算法

Dijkstra算法是典型最短路算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。

Dijkstra算法是很有代表性的最短路算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等。

Dijkstra一般的表述通常有两种方式,一种用永久和临时标号方式,一种是用OPEN, CLOSE表方式,Drew为了和下面要介绍的 A* 算法和 D* 算法表述一致,这里均采用OPEN,CLOSE表的方式。

大概过程:
创建两个表,OPEN, CLOSE。
OPEN表保存所有已生成而未考察的节点,CLOSED表中记录已访问过的节点。
1. 访问路网中里起始点最近且没有被检查过的点,把这个点放入OPEN组中等待检查。
2. 从OPEN表中找出距起始点最近的点,找出这个点的所有子节点,把这个点放到CLOSE表中。
3. 遍历考察这个点的子节点。求出这些子节点距起始点的距离值,放子节点到OPEN表中。
4. 重复2,3,步。直到OPEN表为空,或找到目标点。

提高Dijkstra搜索速度的方法很多,常用的有数据结构采用Binary heap的方法,和用Dijkstra从起始点和终点同时搜索的方法。

A*(A-Star)算法是一种启发式算法,是静态路网中求解最短路最有效的方法。

公式表示为: f(n)=g(n)+h(n),
其中f(n) 是节点n从初始点到目标点的估价函数,
g(n) 是在状态空间中从初始节点到n节点的实际代价,
h(n)是从n到目标节点最佳路径的估计代价。

保证找到最短路径(最优解的)条件,关键在于估价函数h(n)的选取:
估价值h(n)<= n到目标节点的距离实际值,这种情况下,搜索的点数多,搜索范围大,效率低。但能得到最优解。
如果 估价值>实际值, 搜索的点数少,搜索范围小,效率高,但不能保证得到最优解。
估价值与实际值越接近,估价函数取得就越好。
例如对于几何路网来说,可以取两节点间欧几理德距离(直线距离)做为估价值,即f=g(n)+sqrt((dx-nx)*(dx-nx)+(dy-ny)*(dy-ny));这样估价函数f在g值一定的情况下,会或多或少的受估价值h的制约,节点距目标点近,h值小,f值相对就小,能保证最短路的搜索向终点的方向进行。明显优于Dijstra算法的毫无无方向的向四周搜索。
conditions of heuristic
Optimistic (must be less than or equal to the real cost)
As close to the real cost as possible
主要搜索过程:
创建两个表,OPEN表保存所有已生成而未考察的节点,CLOSED表中记录已访问过的节点。
遍历当前节点的各个节点,将n节点放入CLOSE中,取n节点的子节点X,->算X的估价值->
While(OPEN!=NULL)
{
从OPEN表中取估价值f最小的节点n;
if(n节点==目标节点) break;
else
{
if(X in OPEN) 比较两个X的估价值f //注意是同一个节点的两个不同路径的估价值
if( X的估价值小于OPEN表的估价值 )
更新OPEN表中的估价值; //取最小路径的估价值
if(X in CLOSE) 比较两个X的估价值 //注意是同一个节点的两个不同路径的估价值
if( X的估价值小于CLOSE表的估价值 )
更新CLOSE表中的估价值; 把X节点放入OPEN //取最小路径的估价值
if(X not in both)
求X的估价值;
并将X插入OPEN表中; //还没有排序
}
将n节点插入CLOSE表中;
按照估价值将OPEN表中的节点排序; //实际上是比较OPEN表内节点f的大小,从最小路径的节点向下进行。
}

A*算法和Dijistra算法的区别在于有无估价值,Dijistra算法相当于A*算法中估价值为0的情况。

动态路网,最短路算法 D*A* 在静态路网中非常有效(very efficient for static worlds),但不适于在动态路网,环境如权重等不断变化的动态环境下。

D*是动态A*(D-Star,Dynamic A*) 卡内及梅隆机器人中心的Stentz在1994和1995年两篇文章提出,主要用于机器人探路。是火星探测器采用的寻路算法。

主要方法:
1.先用Dijstra算法从目标节点G向起始节点搜索。储存路网中目标点到各个节点的最短路和该位置到目标点的实际值h,k(k为所有变化h之中最小的值,当前为k=h。每个节点包含上一节点到目标点的最短路信息1(2),2(5),5(4),4(7)。则1到4的最短路为1-2-5-4。
原OPEN和CLOSE中节点信息保存。
2.机器人沿最短路开始移动,在移动的下一节点没有变化时,无需计算,利用上一步Dijstra计算出的最短路信息从出发点向后追述即可,当在Y点探测到下一节点X状态发生改变,如堵塞。机器人首先调整自己在当前位置Y到目标点G的实际值h(Y),h(Y)=X到Y的新权值c(X,Y)+X的原实际值h(X).X为下一节点(到目标点方向Y->X->G),Y是当前点。k值取h值变化前后的最小。
3.用A*或其它算法计算,这里假设用A*算法,遍历Y的子节点,点放入CLOSE,调整Y的子节点a的h值,h(a)=h(Y)+Y到子节点a的权重C(Y,a),比较a点是否存在于OPEN和CLOSE中,方法如下:
while()
{
从OPEN表中取k值最小的节点Y;
遍历Y的子节点a,计算a的h值 h(a)=h(Y)+Y到子节点a的权重C(Y,a)
{
if(a in OPEN) 比较两个a的h值
if( a的h值小于OPEN表a的h值 )
{ 更新OPEN表中a的h值;k值取最小的h值
有未受影响的最短路经存在
break;
}
if(a in CLOSE) 比较两个a的h值 //注意是同一个节点的两个不同路径的估价值
if( a的h值小于CLOSE表的h值 )
{
更新CLOSE表中a的h值; k值取最小的h值;将a节点放入OPEN表
有未受影响的最短路经存在
break;
}
if(a not in both)
将a插入OPEN表中; //还没有排序
}
放Y到CLOSE表;
OPEN表比较k值大小进行排序;
}
机器人利用第一步Dijstra计算出的最短路信息从a点到目标点的最短路经进行。

D*算法在动态环境中寻路非常有效,向目标点移动中,只检查最短路径上下一节点或临近节点的变化情况,如机器人寻路等情况。对于距离远的最短路径上发生的变化,则感觉不太适用。

热点内容
如何制作第五人格密码机 发布:2024-11-23 19:44:30 浏览:337
数据库系统的核心是 发布:2024-11-23 19:42:16 浏览:349
linux下载中文版 发布:2024-11-23 19:31:38 浏览:728
gcc按ansi编译 发布:2024-11-23 19:21:12 浏览:699
安卓光遇如何下ios 发布:2024-11-23 19:21:09 浏览:114
内容脚本库 发布:2024-11-23 19:14:31 浏览:361
安卓系统的车机怎么投屏 发布:2024-11-23 19:08:20 浏览:727
php404页面 发布:2024-11-23 19:08:17 浏览:873
安卓如何设置手机快捷方式 发布:2024-11-23 18:30:29 浏览:146
安卓怎么把系统带的软件删了 发布:2024-11-23 18:16:13 浏览:319