K短路(A*算法)

embedded/2024/10/19 13:18:51/

K短路

在图论中,K短路问题是指在一个图中找到从起点s到终点t的第K短的路径。其中,第1短路径即为最短路径。K短路算法在实际应用中有着广泛的用途,如在通信网络中找到替代的最短路径等。

基本概念
  • K短路:从起点s到终点t的第K短的路径。当K=1时,即为最短路径。
  • Dijkstra算法:一种用于求解单源最短路径的贪心算法,但只能找到一条最短路径。
  • A*算法:一种启发式搜索算法,通过估价函数f(n) = g(n) + h(n)来估计从起点到终点的路径长度,其中g(n)是从起点到当前节点的实际代价,h(n)是从当前节点到终点的最佳路径估计代价。
K短路算法的实现
1. 基于Dijkstra和A*的K短路算法

K短路算法的基本思想是在每次迭代中,找到从起点到终点的第K短路径。通常,我们结合Dijkstra算法和A*算法来实现这一目标。

步骤

  1. 预处理:使用Dijkstra算法从终点t反向计算图中每个节点到t的最短路径长度,存储在数组dis[]中。这个步骤是为了计算A*算法中的h(n)。
  2. 初始化:使用优先队列(最小堆)来存储待扩展的路径,队列中的元素包括当前路径的估价f(n)、实际代价g(n)和当前节点v。
  3. 迭代过程
    • 从队列中取出估价最小的节点now。
    • 如果now是终点t,并且这是第k次到达t,则返回当前路径的总代价。
    • 如果now到达t的次数超过k,则跳过此节点。
    • 否则,扩展now节点,生成所有可能的下一节点,并计算其估价f(next) = g(now) + w(now, next) + dis[next],其中w(now, next)是now到next的边的权重。
    • 将新的节点加入队列中。
  4. 结束条件:如果队列为空,表示没有找到第k条路径,返回-1或其他错误标识。

在这里插入图片描述

推荐相关视频学习链接:【B27 A*算法K短路】https://www.bilibili.com/video/BV19k4y1K7gV?vd_source=4c9eb38d8205116069b961c84f64c958

在这里插入图片描述

接下来看一下相关代码(此代码维护二元组)

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
typedef pair<int,int> pii;
const int N = 1e3 + 10, M = 1e5 + 10;int n, m, S, T, K;
int dist[N], st[N], cnt[N];
vector<pii> e[N], ne[N]; //e数组是用来存从终点T到其余各点的边,实际上是没有这些边的,只是将原来的单向边进行反向,就可以表示出从T到其余各点的边
struct node{int s, v, d;bool operator<(const node &x) const{return s > x.s;//如果你使用的是默认的比较函数std::less<T>(或者没有显式指定比较函数,因为std::less<T>是默认的),那么它会调用元素的operator<(如果已定义)。在这种情况下,operator<的bool返回值表示第一个元素是否“小于”第二个元素,而std::priority_queue会将这些“较小”的元素放在堆的底部(尽管它们仍然很容易被访问,但不是最先被移除的)。然而,由于std::priority_queue是一个最大堆,所以实际上被视为“最大”的元素(即那些operator<返回false的元素)会被放置在堆顶。}
};
void dijkstra() {memset(dist, 0x3f, sizeof dist);dist[T] = 0;//这里求的是从T为起点的,到其余各点的最短距离priority_queue<pii, vector<pii>, greater<pii>> q;q.push({0, T});while(q.size()) {int ver = q.top().second, dis = q.top().first;q.pop();if(st[ver]) continue;st[ver] = 1;for(pii t : e[ver]) {int u = t.first, w = t.second;if(!st[u] && dist[ver] + w < dist[u]) {dist[u] = dist[ver] + w;q.push({dist[u], u});}}}
}
int aStar() {priority_queue<node> q; q.push({dist[S], S, 0});while(q.size()) {int ver = q.top().v, dis = q.top().d;q.pop();cnt[ver]++;if(cnt[T] == K) return dis;for(pii t : ne[ver]) {int u = t.first, w = t.second;q.push({dist[u] + dis + w, u, dis + w});}} return 0;
}   
int main() {cin >> n >> m;for(int i = 1; i <= m; i++) {int a, b, c; cin >> a >> b >> c;ne[a].push_back({b, c});//这里建的是单向边e[b].push_back({a, c});//反向建边,和原来边一样,同样是单向边,只不过反向}cin >> S >> T >> K;if(S == T) K++; //这种情况对应有环,即可以自己到自己,第一次从自己出发,所以k++,去掉第一次dijkstra();//先预处理从T到其余各点的最短距离,即预测数组// for(int i = 1; i <= n; i++) {//     cout << "i: " << i << " dist[i]: " << dist[i] << '\n';// }cout << aStar();return 0;
}

在这里插入图片描述

在这里插入图片描述


http://www.ppmy.cn/embedded/93358.html

相关文章

oracle(19c)用户管理

简介 本文介绍 Oracle 中的用户管理&#xff0c;包含以下内容&#xff1a; 概念介绍 系统用户 解锁 hr 用户 创建用户 用户相关案例 使用 Profile 管理用户口令 Oracle 的认证方式 重置管理员(sys)密码 1. 概念介绍 使用前可以自行安装oracle数据库 oracle19c安装&a…

Java进阶篇之super关键字

引言 在前面的文章中&#xff0c;我们介绍了继承的相关概念&#xff08;Java进阶篇之继承的概念&#xff09;&#xff0c;在Java继承机制中&#xff0c;super关键字是一个重要的工具&#xff0c;用于访问父类的属性和方法&#xff0c;特别是在子类覆盖了父类的成员时。通过使用…

手机维修--学习笔记(一)

最近觉得手机主板维修比较有意思&#xff0c;观看许多师傅的维修视频&#xff0c;并做笔记如下&#xff1a; 手机主板维修&#xff1a; 【手机电路板怎么修&#xff0c;师傅对着电路图一步一步讲解&#xff0c;看完受益匪浅】https://www.bilibili.com/video/BV13A411v7wL?v…

pip笔记

pip介绍 pip的全称&#xff1a;package installer for python&#xff0c;也就是Python包管理工具。 配置镜像源 镜像列表 阿里云 http://mirrors.aliyun.com/pypi/simple/中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/豆瓣 http://pypi.douban.com/simple/清华大…

如何将neo4j,4.x版本部署到服务器上

一. 简介 当我们使用neo4j构建知识图谱时&#xff0c;我们希望让别人能和我们共用neo4j进行知识图谱的构建&#xff0c;我们的方法之一就是将neo4j部署到我们的服务器上&#xff0c;然后将7474,7687端口暴露出来&#xff0c;这样就可以通过访问服务器公网IP的7474端口来操作我…

鸿蒙应用服务开发【自定义通知角标】

自定义通知角标 介绍 本示例主要展示了设定应用的桌面图标角标的功能&#xff0c;使用ohos.notificationManager接口&#xff0c;进行桌面角标的设置&#xff0c;通知的发送&#xff0c;获取等。 效果预览 使用说明 在主界面&#xff0c;可以看到当前应用的所有消息通知&am…

【经验分享】ShardingSphere+Springboot-04:自定义分片算法(COMPLEX/STANDARD)

文章目录 3.4 CLASS_BASED 自定义类分片算法3.4.1 复杂分片自定义算法&#xff08;strategyCOMPLEX &#xff09;3.4.2 STANDARD 标准分片自定义算法## 进阶:star: 自定义算法范围查询优化 3.4 CLASS_BASED 自定义类分片算法 3.4.1 复杂分片自定义算法&#xff08;strategyCOM…

Linux部署MySQL8.0

目录 一、部署前准备1.1、查看系统版本和位数&#xff08;32位或64位&#xff09;1.2、下载对应安装包 二、开始部署1、将安装包解压并且移动到目标安装目录2、准备MySQL数据和日志等存储文件夹3、准备MySQL配置文件 my.cnf4、创建mysql单独用户组和用户&#xff0c;将安装目录…