在算法方面,我大部分都是自学成才,而且基本上很好。但是,我在掌握图形算法时遇到了麻烦。我正在寻找具有概念和实际代码的某种参考,因此我不仅可以学习理论(我通常也可以使用),还可以了解图形在实践中如何表示和操作(我通常有更难抓住的时间)。 SO可以提供吗?只要有概念和实施,从书籍,链接到现有项目的任何东西都会很棒。
这是语言无关的,但我对python最熟悉,并且对FP没有太多经验。
答案 0 :(得分:6)
答案 1 :(得分:1)
Steve Yegge说this是一本关于广泛使用图表的算法的好书。
答案 2 :(得分:1)
我从下面链接的书中学到很多关于图表的信息......这是我最喜欢的书之一:
A Course in Combinatorics
J. H. van Lint,R. M. Wilson的 剑桥大学出版社
ISBN 0 521 00601 5
答案 3 :(得分:1)
我建议你研究任何算法时都不要考虑编码。算法完全是数学的,你必须对它们持相同的态度。当你研究像Graph Spanner算法这样的东西时,不要考虑如何编码它如何表示它们。首先要理解为什么算法是重要的和非平凡的。然后尝试一些非常简单的解决方案并比较它们的复杂性。接下来看看最佳解决方案的外观,并尝试推导出它们的属性。使用纸和笔而不是IDE,尝试推导和证明引理等。然后最后看看如何编写伪代码来解决问题。如果你做了这些事情,那么你将与算法建立一种亲密的关系,然后你会发现解决它们要容易得多,因为在编码时你不会想到我为什么这样做。
不幸的是,由于对程序员的巨大需求,现在的程序员不是数学家,他们在解决新问题时遇到问题。早期的程序员如Don Knuth,Mcarthy是数学家和优秀的研究人员。因此,与计算机科学家相比,程序员现在是一个相对便宜的词。
答案 4 :(得分:1)
Bellman-Ford算法: 从源到加权有向图中的所有其他节点的最短路径,即使具有-eve边缘权重(非循环)。比Dijsktra慢但多才多艺。 复杂性:O(| V |。| E |)
BFS:在未加权的无向图中查找从一个给定顶点到其他节点的路径。 复杂性:O(| V | + | E |)。当您知道前方的顶点并使用适当的数据结构时,它会更快,即FIFO Que用于确定已经处理的顶点比复杂度可以减少到 O(| V |)
DFS:查找从源到其他节点的最短路径。在树中以及在图中。图表可能包含循环,这意味着可以一次又一次地访问节点。所以我们可以使用布尔数组来跟踪被访问的节点。否则算法不会停止。 更多的东西看起来越来越深,走到树枝的尽头。 复杂性:O(| V | + | E |)。和复杂度:O(| V |)空间来存储顶点。
Floyed Warshal算法: 查找带有+ eve,-eve(非循环)边缘权重的定向未加权图形中的所有对最短路径。但它不会返回路径本身的细节。 它可用于检测图中的重量循环。当它找到一个它终止。它比较了每对顶点之间通过图形的所有可能路径。所以它使用动态方法而不是贪心方法。 复杂性:O(| V ^ 3 |)
约翰逊的算法:当边权重为+ eve时,找到有向加权稀疏图中的所有对最短路径,但是 - 但不是-eve循环。 它首先使用belman-ford算法从原始图计算变换图。它会移除 - 重量边缘。然后Dijkstra应用于寻找路径。 复杂性:O(V ^ 2 Log V + VE)
Dijkstra算法: 此算法的原始版本不使用优先级,因此复杂性为 O(| V ^ 2 |),但较新版本使用此数据结构,因此复杂性变为 O(E + V log V)< / strong>即可。它是更快的单源最短路径算法。它的工作原理是为访问节点分配一个暂定权重,为访问节点的未访问节点分配无限,查找所有未访问的边缘,并选择最小权重。并将其添加到路径集。
Krushkal的算法:找到MST,在这里找到一个最小可能权重的边缘,在未定向的加权图上连接森林中的任意两棵树。 这是贪心算法。 它还可以找到最小生成森林。 复杂性:O(E log V)
Prim的算法:它找到在无方向加权图上形成树的边缘子集。但是找不到像Krushkal算法那样的MS Forest。
Brouvka的算法:此算法存在的问题是权重在图表中应该是唯一的。它通过检查每个顶点然后放置较小的重量来找到MST。该算法本质上是并行的,但并不比Prim算法快。
与Krushkal算法相同的复杂性。