本文来源于一篇stackexchange的问题回答。提问者问到,我们在计算机科学和数学课程里面学习到的那些算法,到底在什么地方用到了?结果Vijay D给出一个洋洋洒洒的深入回答,得到了提问者和众多围观。我们将这篇回答翻译过来以飨读者。 Vijay D写到: 在我看来,一个系统背后主要发挥作用的算法更容易在非算法课程上找到,这和应用数学中的成果比理论数学中更容易出现在应用中是一个道理。在讲座中,很少有实际问题能够精确匹配到一个抽象问题。归根结底,我认为没有理由让流行的算法课程,诸如Strassen乘法,AKS素性测试、或者Moser-Tardos算法与底层实际问题,如实现视频数据库、优化的编译器、操作系统、网络拥堵控制系统或者其他系统相关。这些课程的价值是学习利用错综复杂的方法发现问题的脉络而找出有效的解决方案。高级算法和简单算法的分析都不简单。正是由于这个原因,我不会忽略简单随机算法或者PageRank。 我想你可以选择任何一个大型软件,并在内部找到它所采用的基础和高级的算法。作为一个研究案例,我选择了Linux内核,并会示例一些Chromium里面的例子。 Linux内核中的基本数据结构和算法Linux内核(源代码的链接在github)。 1.链表、双向链表、无锁链表。 2.B+ 树,这是一些你无法在教科书上找到的说明。
3.优先排序列表 用于 互斥量、驱动等等。 4.红黑树用于调度、虚拟内存管理、追踪文件描述符和目录项等。 5.区间树 6.根树用于内存管理,NFS相关查询和网络相关功能。
7.优先级堆,如其名称的教科书实现,用于cgroup。
8.哈希函数,参考了Knuth和一篇论文。
9.有的代码,比如这个驱动,实现了他们自己的哈希函数。
10.哈希表用于实现inode、文件系统完整性检测等等。 11.位数组用于处理标志位、中断等等。并在Knuth那本书的卷4中阐述。 12.信号量和自旋锁 13.二分查找用于中断处理,寄存器缓存查询等等。 14.B树的二分查找。 15.深度优先搜索被广泛地用于目录配置中。
16.广度优先搜索用于检测运行时锁定的正确性。 17.链表中的归并排序用于垃圾收集、文件系统管理等等。 18.冒泡排序在一个驱动库中也有一个令人惊讶的实现。 19.Knuth-Morris-Pratt 字符串匹配,
20.Boyer-Moore 模式匹配是在找替代品时的参考和建议。
Chromium 浏览器中的数据结构和算法Chromium的(源代码在 Google code)。我只会列出一部分。我建议使用搜索来找到你最喜欢的算法或者数据结构。 1.伸展树。
2.Voronoi算法用于一个示例。 3.基于Bresenham算法的选项卡 在Chromium的第三方代码里面也有如下的数据结构和算法。 1.二叉树 2.红黑树
3.AVL 树 4.Rabin-Karp字符串匹配用于比较。 5.自动机后缀的计算。 6.由Apple公司实现的bloom过滤器。 7.Bresenham 算法。 编程语言库我想这个问题值得思考。编程语言设计者们认为值得花一些工程师的时间和精力来实现这些数据结构和算法,这样其他人就不必这么做了。这些库是我们在JAVA里面比C更少的发现需要重新实现基本数据结构的部分原因。 1.C++ STL包含了链表、栈、队列、映射、向量和排序、搜索和堆操作算法。 2.Java API易于扩展的并且越来越多。 3.Boost C++ 库包含了像 Boyer-Moore以及Knuth-Morris-Pratt字符串匹配算法。 分配和调度算法我发现这些很有趣,因为即使他们被称为启发式,您使用的策略规定了算法类型和需要的数据结构,因此,所以需要人们知道栈和队列。 1.最近最少使用(LRU)算法可以用不同的方法实现。Linux内核有一种基于列表的实现。 2.其他的还有先入先出(FIFO)、最常使用和轮询。 3.FIFO的一个变种用于VAX/VMS系统。 4.Richard Carr的时钟算法用于Linux中的页面替换。 5.Intel i860处理器是一种随机替代策略。 6.自适应置换高速缓存用于一些IBM存储控制器中,也曾经用于PostgreSQL中(虽然仅仅因为一些专利问题)。 7.Knuth在《计算机程序设计艺术 卷1》中讨论过的Buddy内存分配算法内用于Linux内核中,jemalloc并发分配器被用于FreeBSD和facebook中。 *nix系统核心工具1.grep和awk同时从正则表达式中实现NFA的Thompson-McNaughton-Yamada构造,显然这甚至击败了Perl的实现。 2.tsort实现了拓扑排序。 3.fgrep实现了Aho-Corasick字符串匹配算法。 4.GNU grep,根据作者Mike Haertel实现了Boyer-Mooresuan算法。 5.Unix上的crypt(1)实现了一个在Enigma机器上的不同加密算法。 6.Unix diff由Doug McIllroy实现,基于和James Hunt合作编写的原形。它比用于计算Levenshtein距离的标准动态规划算法执行地更好。Linux 版本计算最短编辑距离。 加密算法这本是一个非常长的列表。加密算法在所有执行安全通信和交易的程序中都有实现。 1.Merkle 树,特别是 Tiger Tree Hash变种,被用于点对点应用,比如GTK Gnutella和LimeWire。 2.MD5被用于提供软件包的校验和并被用于在*nix系统上的完整性检测(Linux 实现),同样也支持Windows和OSX。 3.OpenSSL实现了很多加密算法包括AES、Blowfish、DES、SHA-1、SHA-2、RSA、DES等等。 编译器1.LALR 解析在yacc和bison实现。 2.支配算法被用于大多数基于SSA形式的编译器优化。 3.lex和flex将正则表达式编译为NFA。 压缩和图像处理1.用于GIF图片格式的Lempel-Ziv算法在图像处理程序中实现,从*unix工具转化到复杂的程序。 2.行程长度编码用于产生PCX文件(用于原来的画笔程序),它是被压缩的BMP和TIFF文件。 3.小波压缩是JPEG2000的基础,所以所有生成JPEG2000文件的数码相机会支持这个算法。 4.Reed-Solomon纠错在Linux内核、CD驱动器、条形码读取器、结合从Voyager中的卷积图像传输中实现。 冲突驱动语句学习算法 (CDCL)自2000年以来,SAT求解器在工业标准的运行时间(通常是硬件工业,虽然其他地方也被使用)以近乎指数的方式每年下跌。这发展中很重要的一部分是冲突驱动语句学习算法,它结合了Davis Logemann和Loveland在约束规划和人工智能研究中关于语句学习的原始论文中的布尔约束传播算法。特定地,工业造型,SAT被认为是一个简单的问题(见这个讨论)。对我而言,这个一个最近最好的成功故事,因为它结合了这几年算法的不断发展、清晰的工程理念、实验性的评估、齐心协力地解决一个问题。Malik 和 Zhang的CACM文章值得阅读。这个算法在许多大学中教授(我参加过的4个地方都是如此),但是通常在一个逻辑或者形式方法课上。 SAT求解器的应用有很多。IBM,Intel和许多其他公司都有他们的SAT求解器实现。OpenSuse的包管理器同样使用了一个SAT求解器。 |