A*算法是一类贪心算法,其可以用于寻找最优路径。我们可以利用A*算法来求第k短路径。

  一条路径可以由两部分组成,第一部分是一个从出发到达任意点的任意路径,而第二部分是从第一部分的末端出发,到终点的最短路径。两部分正好可以组成一条路径,且每一条路径都可以分解这两部分(允许任意一部分为空)。因此当我们已知第一部分的路径A时,设第二部分为B,我们可以尝试预估完整的路径A+B的费用(距离),我们将公式定义为:f(A)=g(A)+h(A)。其中g(A)表示第一部分A的已知长度,而h(A)表示路径A到终点的预估最短距离,而f(A)表示路径A的预估总费用。由于A*是贪心算法,因此我们每次都会选择预估总费用最低的路径,并在进行拓展。

  下面说明如何用A*算法求解第k短路径。首先我们需要计算从所有结点到终点的最短路径(以终点为起点逆向跑最短路算法)。之后我们维护一个最小堆,在一开始将起点代表的路径加入堆中。我们对路径的评估采用A*的方式,由于每个结点到终点的距离已知,因此h(A)也是确定而非预估的。每次都从堆中取预估费用最小的路径并在其上进行拓展(访问相邻的所有结点并创建新的路径加入堆中,允许新路径上出现重复结点),并将最小路径从堆中移除。在上面过程中我们每次发现路径的末尾是终点,则进行一次计数,直到计数为k,则我们找到了第k短路径。

  由于采用的是BFS方式扩展路径,因此可以保证存储在堆中的路径都是不同的。每次找到的最短路径必然是所以以残留在堆中的路径为前缀的从起点到终点的最短路径,可以知道依序找到的路径1,2,...其费用必定非严格递增。而第一次找到的路径显然是最短的。若前n-1次找到的路径是前n-1短的,我们可以保证第n短的路径的某个前缀保留在堆中。若第n短的路径与前n-1条找到的最短路径的最长相同前缀均为0,那么可以保证这个前缀必然是未被消耗的(所有的路径的公共前缀起点在一开始就加入了最小堆中)。而若第n短的路径与第t短路径有最长前缀p,那么两条路径t与路径n的第p+1个结点互不相同,但是由于计算第t短路径时,我们会将路径n的p+1长前缀创建并加入堆中,且一直到第n-1条路径出堆,该p+1长前缀都不会出堆,所以此时该前缀依旧存在于最小堆中。故下一次找到的路径是第n短的路径。

  下面说明时间复杂度,利用Dijkstra算法可以在O(|E|log2(|V|))时间复杂度内计算最短路径。之后我们计算每次从堆中弹出完整路径(从起点出发抵达终点的路径)过程中最多有|V|条路径被弹出(最短路径不含环),且这过程中最多有|E|个结点被加入堆中。故堆中最多含有k|E|条路径,因此总的时间复杂度为O(k*(|V|+|E|)log2(k|E|))+O(|E|log2(|V|))=O(k|E|log2(k|E|))。

A* 算法求第k短路径的更多相关文章

  1. POJ 2449 Remmarguts' Date (第k短路径)

    Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Submissions:35025   Accepted: 9467 ...

  2. A* 算法求第 K 短路

    一种具有 \(f(n)=g(n)+h(n)\) 策略的启发式算法能成为 A* 算法的充分条件是: 搜索树上存在着从起始点到终了点的最优路径. 问题域是有限的. 所有结点的子结点的搜索代价值 \(> ...

  3. POJ 3613 快速幂+Floyd变形(求限制k条路径的最短路)

    题意:       给你一个无向图,然后给了一个起点s和终点e,然后问从s到e的最短路是多少,中途有一个限制,那就是必须走k条边,路径可以反复走. 思路:       感觉很赞的一个题目,据说证明是什 ...

  4. poj 2449 第k短路径

    思路: 利用一个估计函数g[i]=dis[i]+len.其中len为队列出来的点当前已经走了的距离.dis[i]为该点到终点的最短路径.这样我们只要将点按g[i]的升序在队列你排序,每次取出最小的g[ ...

  5. aStar算法求第k短路

    A*的概念主意在于估计函数,f(n)=g(n)+h(n),f(n)是估计函数,g(n)是n节点的当前代价,h(n)是n节点的估计代价:而实际中,存在最优的估计函数f'(n)=g'(n)+h'(n),那 ...

  6. [BFS,A*,k短路径] 2019中国大学生程序设计竞赛(CCPC) - 网络选拔赛 path (Problem - 6705)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=6705 path Time Limit: 2000/2000 MS (Java/Others)    Mem ...

  7. A*算法的认识与求第K短路模板

    现在来了解A*算法是什么 现在来解决A*求K短路问题 在一个有权图中,从起点到终点最短的路径成为最短路,第2短的路成为次短路,第3短的路成为第3短路,依此类推,第k短的路成为第k短路.那么,第k短路怎 ...

  8. POJ - 3255 SPFA+邻接表求次短路径

    题意:给出m条边 , n个顶点,u [ i ]到v [ i ] 的距离w [ i ],求除了最短路的那条最短的边的长度. 思路:之前有做过相似的题,使用迪杰斯特拉算法求单源最短路径,并且记录路径,枚举 ...

  9. POJ 3255 Roadblocks (Dijkstra求最短路径的变形)(Dijkstra求次短路径)

    Roadblocks Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16425   Accepted: 5797 Descr ...

随机推荐

  1. drone 学习三 条件步骤

    1. 基本格式 pipeline: slack: image: plugins/slack channel: dev + when: + branch: master 2. 几种条件类型 a. bra ...

  2. openresty && hashids&& redis 生成短链接

    1. 原理     a. 从redis 获取需要表示的短链接的id( redis incr)     b. hashids 编码 id     c. openresty  conteent_by_lu ...

  3. CentOS6.5安装Cacti统计图乱码解决

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://fengwan.blog.51cto.com/508652/1430505 这个就 ...

  4. 服务器用 git 进行部署出现代码冲突的处理

    服务器用 git 进行部署出现代码冲突的处理 起因: 由于项目是之前很久之前上传的,且并没上线.使用 git pull 进行代码更新时出现很多冲突. 因为服务器上的代码有移动过位置,不知道为什么就冲突 ...

  5. Docker容器编排器概览

    就像Apple推出iPhone让智能手机变成主流,Docker让容器变成了主流.自从项目发布以来,Docker着重于提升开发者的体验.基本理念是可以在整个行业中,在一个标准的框架上,构建.交付并且运行 ...

  6. oracle之 12.1.0.1.0 C 在 linux 7 上安装报错处理

    环境说明:-- os[root@host-172-16-3-132 ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) - ...

  7. JDBC查询实例

    作为Java与数据库交互最古老的.最基础的规范,JDBC提供了访问底层数据库的接口,其他ORM框架都是在JDBC这块基石上构建的.下面我们看一个基本的JDBC查询例子: package com.ins ...

  8. 修改配置文件matplotlibrc,让Matplotlib显示中文

    matplotlib默认不支持中文显示,网上的解决办法有好多种,但是大多数都是通过在代码中指定字体,虽然也能实现,但是多出那么几行代码让人觉得很恶心. 本文介绍一种通过修改配置文件matplotlib ...

  9. iso网络模型

    tcp/ip知识 1.iOS七层模型 应用层 表示层 应用层 ssh httpssl tls ftp mime html snmp 会话层 传输层 传输层 tcp udp 网络层 网络层 ipv6 i ...

  10. MySQL的Query Cache原理分析

    QueryCache(下面简称QC)是根据SQL语句来cache的.一个SQL查询如果以select开头,那么MySQL服务器将尝试对其使用QC.每个Cache都是以SQL文本作为key来存的. 原理 ...