K短路(A*算法)

news2024/9/23 14:17:58

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.coloradmin.cn/o/1996611.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

美国服务器稳定么?影响服务器稳定性的6个因素

美国服务器稳定么&#xff1f;美国服务器的稳定性是相当不错的&#xff0c;这主要得益于其先进的技术、成熟的基础设施以及严格的管理措施。美国拥有众多知名的服务器提供商&#xff0c;这些提供商通常会采用顶级的硬件设施&#xff0c;如英特尔、AMD等知名品牌的处理器&#x…

Chromium编译指南2024 - Android篇:前置要求(一)

1.引言 欢迎阅读《Chromium编译指南2024 - Android篇》。本指南旨在帮助开发者理解和掌握在Android平台上编译Chromium的全过程。Chromium是一个开源的浏览器项目&#xff0c;由Google主导开发&#xff0c;并为多个现代浏览器提供基础代码。Android作为全球使用最广泛的移动操…

DirectX_web_setup.exe

F:\Downloads\录屏软件\OBS DirectX_web_setup.exe

IP实现https访问的简易方式

很多项目怕麻烦不愿意申请域名&#xff0c;也不想备案&#xff0c;所以直接用服务器IP地址做WEB项目更快一些&#xff0c;但又想给IP地址申请SSL证书&#xff0c;这种情况下需要用到IP类型的专用SSL证书。 IP SSL证书是支持IP地址实现HTTPS加密的SSL证书&#xff0c;为不能提供…

Linux服务管理(五)Apache服务优化

CustomLog "|/bin/rotatelogs -l /wwwlogs/access_%Y%m%d.log 86400" combined日志旋转可参考这篇文章&#xff1a; https://blog.csdn.net/weixin_43576565/article/details/139989701 要优化首先你得有Apache yum -y install httpd启动 service httpd start写入…

[Qt][按钮类控件]详细讲解

目录 0.按钮状态说明1.Push Button2.Radio Button3.Check Box4.Tool Button 0.按钮状态说明 clicked&#xff1a;⼀次 ⿏标按下⿏标释放 触发pressed&#xff1a;鼠标按下时触发released&#xff1a;鼠标释放时触发toggled&#xff1a;checked属性改变时触发 1.Push Button QP…

seaborn与pandas绘图入门

导入环境 import numpy as np import pandas as pd from numpy.random import randn import matplotlib.pyplot as plt 若是在jupyter notebook编译&#xff0c;需要额外执行下列语句 %matplotlib notebook 该语句在Jupyter Notebook或JupyterLab中使用的IPython魔法命令&…

最新版的AutoGPT,我搭建好了

最近AutoGPT不是更新了嘛 安装 我按照官方的教程 在本地搭建好了 改动 可见的改动&#xff0c;主要是把原来的纯命令行改成前后端的形式 看下前端界面 界面比较简单&#xff0c;主要分3个大块 监控 第一个是监控 主要是看你在 build 里构建的Agents的运行情况 build 第一个是Ag…

C++笔试练习笔记【7】:力扣 91. 解码方法 动态规划练习

文章目录 题目题目分析思路解法正常解法优化解法 题目 题目链接&#xff1a;力扣 91. 解码方法 备用链接&#xff1a;https://leetcode.cn/problems/decode-ways/description/ 题目分析 1.首先我们知道题目给定A~Z编码为1 ~26 &#xff0c;而数字十一字符串的形式给出所以…

js构造函数的prototype赋值总结

我们知道通过构造函数的prototype,可以生成让所有实例对象访问的通用属性和方法,下面通过代码来解释这个过程 function Person(name){this.name name; }Person.prototype.sex man我们定义了一个构造函数Person,然后给它的prototype添加了一个sex的属性,下面我们来看看Person…

MySQL:复杂查询 (一)——聚合函数分组查询联合查询

目录 1、聚合查询 1.1 聚合函数 1.1.1 COUNT() 1.1.2 SUM() 1.1.3 AVG() 1.1.4 MAX()&#xff0c;MIN() 1.2 分组查询 1.2.1 GROUP BY子句 1.2.1.1 round() 1.2.2 HAVING 1.2.3 示例 2、联合查询 2.1 ①取相关表笛卡尔积 2.2 ②过滤无效数据 2.3 ③精简查询结果…

【数据结构】队列,你必须知道的内部原理!!!

&#x1f31e;&#x1f31e;&#x1f31e;生活本就沉闷&#xff0c;但跑起来就会有风 ~~~ 前言&#xff1a; &#x1f31f;&#x1f31f;Hello家人们&#xff0c;这期讲解数据结构队列的基础知识&#xff0c;希望你能帮到屏幕前的你。 &#x1f4da;️上期博客在这里&#xff1…

书生基础岛1-开发全链路

涌现能力&#xff1a;知识到运用的能力。 开源工具箱&#xff1a; 预训练&#xff1a; 微调&#xff1a; 部署&#xff1a; 智能体&#xff1a; 智能体&#xff1a; 知识库构建&#xff1a; RAG&#xff1a;

初识C++ · C++11(1)

目录 前言&#xff1a; 1 统一列表初始化 2 声明 2.1 auto 2.2 decltype 2.3 nullptr 2.4 stl的部分变化 3 右值引用和移动语义 前言&#xff1a; 在C11之前&#xff0c;C98的出现使得C看起来更像是一门独立的语言&#xff0c;C委员会成立后&#xff0c;对外宣称的是5…

神鸟云PCDN业务招募

短Z业务--支持nat0~nat4 省内调度&#xff0c;晚高峰 跑量9成 配置要求: 线路&#xff1a;单条上行30M 硬件&#xff1a;32线程 64内存条 240G系统盘 1G:2T固态盘单价&#xff1a;移动1900 电联2500 镜像下载&#xff1a;http://oss.download.birdicloud.com/box/Cent…

三层架构:IOCDI

三层架构 我们先看一下三层架构是什么 我们想要实现这三层架构的分离&#xff0c;实现一个类实现一个功能。 我们先建立一个包&#xff0c;然后在包下创建接口&#xff0c;然后再实现接口。从而实现三层架构分离。 IOC 为了实现这三层架构的分离&#xff0c;我们把创建类的…

协同过滤之矩阵分解算法问题详解

1、矩阵分解出现的原因 传统的协同过滤依赖用户的历史行为来推测用户对未评分商品的评分&#xff08;潜在兴趣&#xff09;&#xff0c;不需要了解物品的具体属性&#xff0c;也不需要知道用户的具体偏好&#xff0c;只需要历史评分数据就可以进行推荐&#xff0c;存在以下问题…

Query @azure/openai with images?

题意&#xff1a;使用图像与azure/openai进行交互或查询 问题背景&#xff1a; On chat.openai.com I can upload an image and ask chatgpt a question about it, with the existing openai and azure/openai api however there doesnt seem to be a way to do this? The Ch…

QT+ffmpeg环境配置

1.新建一个qt项目 2.下载ffmpeg文件Releases BtbN/FFmpeg-Builds GitHub 3.解压后&#xff0c;打开qt项目地址&#xff0c;将ffmpeg文件复制进qt项目 4.打开新建的qt项目头文件新加入如下内容&#xff1a;&#xff08;如有需求可按需求添加&#xff09; INCLUDEPATH $$PWD/i…

【多线程-从零开始-捌】阻塞队列,消费者生产者模型

什么是阻塞队列 阻塞队里是在普通的队列&#xff08;先进先出队列&#xff09;基础上&#xff0c;做出了扩充 线程安全 标准库中原有的队列 Queue 和其子类&#xff0c;默认都是线程不安全的 具有阻塞特性 如果队列为空&#xff0c;进行出队列操作&#xff0c;此时就会出现阻…