算法学习和实践 ---- Shortest Path Problem

Preface: 
     计算机领域问题解决的最为关键的两大部分就是问题模型和对应的算法。模型中包括问题的描述以及对应使用的数据结构等等。而算法则是基于模型上解决该问题的方法。这两大部分可以说是计算机科学中最为关键的部分,因此这个文章分类中主要以两大部分,其中”算法学习和实践“开头的便是算法篇;以“模型和数据结构”为开头的便是数学模型和数据结构方面的知识。

     算法学习和实践主要是以两条主线展开:一,以算法设计的思想和方法为主线。探讨不同种的算法设计思想和方法在不同的问题中的应用,无疑算法设计的学习和实践过程中掌握一个算法本身不是关键,关键是掌握算法背后的设计思想。这条线的划分也是大部分算法书目章节的主要划分方法。二,以问题为主线,即以常见的各种Problem为主线进行学习。对于一个Problem往往有诸多的应用场景以及诸多的引申问题。针对不同的问题可能产生不同的算法。
     算法学习的书目主要是: 《算法导论》, 《算法设计技巧和分析》. 学习和总结的方法:首先,需要对算法基于的数学模型十分了解。其次,对于算法要解决的问题,包括问题的描述、问题的应用、问题的变形以及解决。第三,常见算法的理论学习,包括算法的基本思想,设计的灵感和初衷;算法的深入分析(算法的复杂度、算法改进的空间等)。第四,算法的实践。代码实践,主要以最为常用的算法为实例进行基于C语言的实现。

PS: 由于总结的过程可能比较乱和比较随行。各个主题之间的顺序也主要是以我学习的顺序为主。

Content.

Shortest Path Problem

1. Definition

最短路径问题是指对于能够利用图模型进行建模的问题,求其中vertex V 和U 之间的

最短路径。根据问题侧重点又可以分为几种:

1) Single-pair shortest path problem.

2) Single-source shortest path problem

3) Single-destination shortest path problem

4) All-pairs shortest path problem

2. Algorithms

The most important algorithms for solving this problem are:

§ Dijkstra's algorithm solves the single-pair, single-source, and single-destination shortest path problems.

§ Bellman-Ford algorithm solves the single source problem if edge weights may be negative.

§ A* search algorithm solves for single pair shortest path using heuristics to try to speed up the search.

§ Floyd-Warshall algorithm solves all pairs shortest paths.

§ Johnson's algorithm solves all pairs shortest paths, and may be faster than Floyd-Warshall on sparse graphs.

§ Perturbation theory finds (at worst) the locally shortest path.

Additional algorithms and associated evaluations may be found in Cherkassky et al.[1]

3. Application

最短路径问题的应用十分的广泛,凡是可以利用图模型进行建模最后将问题转化为最短

路径问题都可以利用这些算法进行求解。较为常见的包括:Network Routing, Map path.而且如果将某一些问题的状态看做图模型中的一个点,状态的转换作为其中的边那么很多达到某个状态的最优策略问题同样可以转换为最短路径问题。

4. Details of Common Algorithms.

最常用的两个算法就是Dijkstra's algorithm, Bellman-Ford Algorithm.

1) Dijkstra’s Algorithm (for single-source)

I.算法思想:对于边的权值为非负的图模型,由源点出发逐层的确定最短路径。利

贪婪的思想在每一层中确定最短的路径,同时更新以此点为中间点可达的点的距离。循环的选择点直到所有的点的最短路径都确定。

算法的基本流程见PPT.

II.有一个关键的操作 --- Relax edge. 称为边的松弛,事实上就是比较原先的距离与其他点的距离被更新后带来的距离变化。

III.在原先的算法基础上如果在每一个点的最短路径确认的同时保存其parent edge则可以生成一个shortest path tree.

IV. 算法复杂度分析,时间复杂度为??

编程代码.

2) Bellman-Ford Algorithm

对于Dijkstra 算法由于算法本身是基于逐层的路径拓展,因此其中便假设路径的长度

是随着层次的增加而增加,而如果有负权值的边出现那么这个前提就被打破,算法就失效。

I. 算法的基本思想:

理论依据: 首先,对于图G = (V,E)其中点的个数为n,边的数目为m. 那么如果对

于图G有从源点S的最短路径存在,路径的边数不超过n-1;而且路径上不包含正权值回路或者是负权值回路。其次,最短路径问题本身符合最佳定理,因此某个点的最短距离可以由与其相连的边上的点的距离来进行更新比较得到。

算法流程:基于上述依据,则如果点存在最短路径则以下步骤可以得到:

Bellman-Ford算法流程分为三个阶段:

(1)初始化:将除源点外的所有顶点的最短距离估计值 d[v] ←+∞, d[s] ←0;

(2)迭代求解:反复对边集E中的每条边进行松弛操作,使得顶点集V中的每个顶点v的最短距离估计值逐步逼近其最短距离;(运行|v|-1次)

(3) 检验负权回路:判断边集E中的每一条边的两个端点是否收敛。如果存在未收敛的顶点,则算法返回false,表明问题无解;否则算法返回true,并且从源点可达的顶点v的最短距离保存在 d[v]中。

II.算法的分析:时间的复杂度为O(nm).传统的Bellman-Ford算法由于是以最坏的情况来进行循环的进行边的松弛和比较。事实上,没进行一次就确定一层最短路径,因此这个部分由改进的空间。改进的算法为SPFA(Shortest path faster algorithm).

编程代码: TraditionalBF.c

                   SPFA.c

Reference:

[1] http://baike.baidu.com/view/1481053.htm#2

[2] http://2728green-rock.blog.163.com/blog/static/43636790200901211848284/

[3]http://hi.baidu.com/%CC%EC%BF%D5%D6%AE%B3%C7xin/blog/item/98966faa3d7820f11f17a227.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值