Fork me on GitHub
共21页: 上一页 1 2 3 4 5 6 7 8 9 下一页 末页 
摘要: 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 匠心十年 阅读(12490) 评论(0) 编辑
摘要: 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 匠心十年 阅读(23361) 评论(4) 编辑
摘要: Prim 算法是一种解决最小生成树问题(Minimum Spanning Tree)的算法。和 Kruskal 算法类似,Prim 算法的设计也是基于贪心算法(Greedy algorithm)。Prim 算法的思想很简单,一棵生成树必须连接所有的顶点,而要保持最小权重则每次选择邻接的边时要选择较小权重的边。Prim 算法看起来非常类似于单源最短路径 Dijkstra 算法,从源点出发,寻找当前的最短路径,每次比较当前可达邻接顶点中最小的一个边加入到生成树中。阅读全文
posted @ 2015-01-31 09:23 匠心十年 阅读(1385) 评论(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 匠心十年 阅读(4368) 评论(2) 编辑
摘要: 给定一个有向图 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 匠心十年 阅读(1706) 评论(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 匠心十年 阅读(1099) 评论(0) 编辑
摘要: Union-Find 算法为不相交集合数据结构中的非常有用的操作。其通常使用链表或一维数组来实现,另一种实现方式是使用有根树来表示集合,树中的每个节点都包含集合的一个成员,每棵树表示一个集合,形成不相交集合森林(Disjoint-set forest)。每棵树的根包含了集合的代表,并且是它自己的父节点。通过引入两种启发式策略,可以获得目前已知的、渐进意义上最快的不想交集合数据结构。第一种启发式策略是按秩合并(Union by Rank),其思想是使包含较少节点的树的根指向包含较多节点的树的根。第二种启发式策略是路径压缩(Path Compression),在 Find 操作中,使查找路径上的每个节点都直接指向根节点。路径压缩并不改变节点的秩(Rank)。阅读全文
posted @ 2015-01-30 20:50 匠心十年 阅读(1431) 评论(0) 编辑
摘要: 不相交集合数据结构(Disjoint-set)是一种用于跟踪集合被分割成多个不相交的子集合的数据结构。Union-Find 算法为该数据结构提供了两种非常有用的操作:Find:判断子集合中是否存在特定的元素。可以用于检测是否两个元素存在于相同的子集合中。Union:将两个不子集合合并成新的子集合。Union-Find 算法的一个具体的应用就是在无向图(Undirected Graph)中检测是否存在环。阅读全文
posted @ 2015-01-30 20:49 匠心十年 阅读(1707) 评论(1) 编辑
摘要: 给定有向图 G = (V, E),需要判断该图中是否存在环路(Cycle)。深度优先搜索(DFS:Depth-First Search)可以用于检测图中是否存在环。DFS 会对一个连通的图构造一颗树,如果在构造树的过程中出现反向边(Back Edge),则认为图中存在环路。对于非连通图,可以对图中的不同部分分别进行 DFS 构造树结构,对于每棵树分别检测反向边的存在。在 DFS 对图进行遍历时,将遍历过的顶点放入递归栈中,如果新遍历的顶点已经存在于递归栈中,则说明存在一个反向边,即存在一个环。阅读全文
posted @ 2015-01-30 20:48 匠心十年 阅读(6540) 评论(0) 编辑
摘要: 深度优先搜索(DFS:Depth-First Search)是一种图搜索策略,其将搜索限制到 2 种操作:(a) 访问图中的一个节点;(b) 访问该节点的子节点。对图的深度优先搜索与对树(Tree)的深度优先遍历(Depth First Traversal)是类似的,区别在于图中可能存在环,所以可能会遍历到已经遍历的节点。阅读全文
posted @ 2015-01-30 20:46 匠心十年 阅读(2243) 评论(0) 编辑
共21页: 上一页 1 2 3 4 5 6 7 8 9 下一页 末页