上一页 1 2 3 4 5 6 ··· 21 下一页
摘要: 对于全源最短路径问题(All-Pairs Shortest Paths Problem),可以认为是单源最短路径问题的推广,即分别以每个顶点作为源顶点并求其至其它顶点的最短距离。Johnson 算法描述如下:给定图 G = (V, E),增加一个新的顶点 s,使 s 指向图 G 中的所有顶点都建立连接,设新的图为 G’;对图 G’ 中顶点 s 使用 Bellman-Ford 算法计算单源最短路径,得到结果 h[] = {h[0], h[1], .. h[V-1]};对原图 G 中的所有边进行 "re-weight",即对于每个边 (u, v),其新的权值为 w(u, v) + (h[u] - h[v]);移除新增的顶点 s,对每个顶点运行 Dijkstra 算法求得最短路径;Johnson 算法的运行时间为 O(V2logV + VE)。 阅读全文
posted @ 2015-02-02 08:33 sangmado 阅读(24493) 评论(3) 推荐(13) 编辑
摘要: Floyd-Warshall 算法采用动态规划方案来解决在一个有向图 G = (V, E) 上每对顶点间的最短路径问题,其中图 G 允许存在权值为负的边,但不存在权值为负的回路。Floyd-Warshall 算法的运行时间为 Θ(V^3)。Floyd-Warshall 算法的设计基于了如下观察。设带权图 G = (V, E) 中的所有顶点 V = {1, 2, . . . , n},考虑一个顶点子集 {1, 2, . . . , k}。对于任意对顶点 i, j,考虑从顶点 i 到 j 的所有路径的中间顶点都来自该子集 {1, 2, . . . , k},设 p 是该子集中的最短路径。Floyd-Warshall 算法描述了 p 与 i, j 间最短路径及中间顶点集合 {1, 2, . . . , k - 1} 的关系,该关系依赖于 k 是否是路径 p 上的一个中间顶点。 阅读全文
posted @ 2015-02-02 08:32 sangmado 阅读(13444) 评论(6) 推荐(3) 编辑
摘要: Dijkstra 算法又称为单源最短路径算法,由计算机科学家 Edsger Dijkstra 于 1956 年构思并于 1959 年发表。其解决的问题是:给定图 G 和源顶点 v,找到从 v 至图中所有顶点的最短路径。Dijkstra 算法的初始实现版本并未使用最小优先队列实现,其时间复杂度为 O(V^2)。Leyzorek et al 在 1957 提供了基于 Fibonacci heap 的最小优先队列实现版本,其时间复杂度为 O(VlogV)。 阅读全文
posted @ 2015-02-02 08:30 sangmado 阅读(39687) 评论(0) 推荐(2) 编辑
摘要: Bellman-Ford 算法是一种用于计算带权有向图中单源最短路径的算法。该算法由 Richard Bellman 和 Lester Ford 分别发表于 1958 年和 1956 年。Bellman-Ford 算法和 Dijkstra 算法同为解决单源最短路径的算法。对于带权有向图 G = (V, E),Dijkstra 算法要求图 G 中边的权值均为非负,而 Bellman-Ford 算法能适应一般的情况(即存在负权边的情况)。Bellman-Ford 算法的时间复杂度为 O(V*E),其中 V 为顶点数量,E 为边的数量。 阅读全文
posted @ 2015-02-02 08:29 sangmado 阅读(69480) 评论(5) 推荐(12) 编辑
摘要: Prim 算法是一种解决最小生成树问题(Minimum Spanning Tree)的算法。和 Kruskal 算法类似,Prim 算法的设计也是基于贪心算法(Greedy algorithm)。Prim 算法的思想很简单,一棵生成树必须连接所有的顶点,而要保持最小权重则每次选择邻接的边时要选择较小权重的边。Prim 算法看起来非常类似于单源最短路径 Dijkstra 算法,从源点出发,寻找当前的最短路径,每次比较当前可达邻接顶点中最小的一个边加入到生成树中。 阅读全文
posted @ 2015-01-31 09:23 sangmado 阅读(2990) 评论(0) 推荐(0) 编辑
摘要: 对于一个给定的连通的无向图 G = (V, E),希望找到一个无回路的子集 T,T 是 E 的子集,它连接了所有的顶点,且其权值之和为最小。因为 T 无回路且连接所有的顶点,所以它必然是一棵树,称为生成树(Spanning Tree),因为它生成了图 G。显然,由于树 T 连接了所有的顶点,所以树 T 有 V - 1 条边。一张图 G 可以有很多棵生成树,而把确定权值最小的树 T 的问题称为最小生成树问题(Minimum Spanning Tree)。术语 "最小生成树" 实际上是 "最小权值生成树" 的缩写。Kruskal 算法提供一种在 O(ElogV) 运行时间确定最小生成树的方案。Kruskal 算法基于贪心算法(Greedy Algorithm)的思想进行设计,其选择的贪心策略就是,每次都选择权重最小的但未形成环路的边加入到生成树中。 阅读全文
posted @ 2015-01-31 09:22 sangmado 阅读(10233) 评论(2) 推荐(5) 编辑
摘要: 给定一个有向图 G = (V, E) ,对于任意一对顶点 u 和 v,有 u --> v 和 v --> u,亦即,顶点 u 和 v 是互相可达的,则说明该图 G 是强连通的(Strongly Connected)。如下图中,任意两个顶点都是互相可达的。实际上,解决该问题的较好的方式就是使用强连通分支算法(SCC:Strongly Connected Components),可以在 O(V+E) 时间内找到所有的 SCC。如果 SCC 的数量是 1,则说明整个图是强连通的。实现 SCC 的一种算法就是 Kosaraju 算法。Kosaraju 算法基于深度优先搜索(DFS),并对图进行两次 DFS 遍历。Kosaraju 算法的思想就是,如果从顶点 v 可以抵达所有顶点,并且所有顶点都可以抵达 v,则说明图是强连通的。 阅读全文
posted @ 2015-01-30 22:29 sangmado 阅读(4279) 评论(0) 推荐(0) 编辑
摘要: 有向图 G = (V, E) 的一个强连通分支(SCC:Strongly Connected Components)是一个最大的顶点集合 C,C 是 V 的子集,对于 C 中的每一对顶点 u 和 v,有 u --> v 和 v --> u,亦即,顶点 u 和 v 是互相可达的。通过 Kosaraju 算法,可以在 O(V+E) 运行时间内找到所有的强连通分支。Kosaraju 算法是基于深度优先搜索(DFS),算法的描述如下:创建一个空的栈 S,并做一次 DFS 遍历。在 DFS 遍历中,当在递归调用 DSF 访问邻接顶点时,将当前顶点压入栈中;置换图(Transpose Graph);从栈 S 中逐个弹出顶点 v,以 v 为源点进行 DFS 遍历。从 v 开始的 DFS 遍历将输出 v 关联的强连通分支。 阅读全文
posted @ 2015-01-30 22:28 sangmado 阅读(2482) 评论(0) 推荐(1) 编辑
摘要: Union-Find 算法为不相交集合数据结构中的非常有用的操作。其通常使用链表或一维数组来实现,另一种实现方式是使用有根树来表示集合,树中的每个节点都包含集合的一个成员,每棵树表示一个集合,形成不相交集合森林(Disjoint-set forest)。每棵树的根包含了集合的代表,并且是它自己的父节点。通过引入两种启发式策略,可以获得目前已知的、渐进意义上最快的不想交集合数据结构。第一种启发式策略是按秩合并(Union by Rank),其思想是使包含较少节点的树的根指向包含较多节点的树的根。第二种启发式策略是路径压缩(Path Compression),在 Find 操作中,使查找路径上的每个节点都直接指向根节点。路径压缩并不改变节点的秩(Rank)。 阅读全文
posted @ 2015-01-30 20:50 sangmado 阅读(2846) 评论(0) 推荐(1) 编辑
摘要: 不相交集合数据结构(Disjoint-set)是一种用于跟踪集合被分割成多个不相交的子集合的数据结构。Union-Find 算法为该数据结构提供了两种非常有用的操作:Find:判断子集合中是否存在特定的元素。可以用于检测是否两个元素存在于相同的子集合中。Union:将两个不子集合合并成新的子集合。Union-Find 算法的一个具体的应用就是在无向图(Undirected Graph)中检测是否存在环。 阅读全文
posted @ 2015-01-30 20:49 sangmado 阅读(3457) 评论(1) 推荐(2) 编辑
上一页 1 2 3 4 5 6 ··· 21 下一页