简体   繁体   English

动态编程算法和实际使用情况

[英]Dynamic Programming algorithms and real world usage

I have studied in the past the classical DP problems and algorithms (coins, longest increasing subsequence, longest common subsequence, etc). 过去,我研究了经典的DP问题和算法(硬币,最长的增长子序列,最长的公共子序列等)。

I know that these algorithms have practical applications (ie. genetic algorithms, just to name one). 我知道这些算法有实际应用(例如,遗传算法,仅举一例)。 What I question though is if these algorithms have practical applications in modern computer science, where the size of input is very large and problems are not solvable on just one machine. 我要问的是,这些算法是否可以在现代计算机科学中得到实际应用,在现代计算机科学中,输入量很大,并且不能在一台机器上解决问题。

My point is that these algorithms are quite hard to parallelize (ie. Parallel Dynamic Programming ), and memory occupation is quadratic in most of the formulations, making it hard to process inputs that are reasonably big. 我的观点是,这些算法很难并行化(即并行动态编程 ),并且在大多数公式中内存占用是二次的,因此很难处理相当大的输入。

Anyone has real world use cases on this? 有人对此有现实用例吗?

Practical application: diff . 实际应用: diff This is an essential Linux utility which finds the differences between two files by solving the longest common subsequence problem using the DP algorithm. 这是一个必不可少的Linux实用程序,它通过使用DP算法解决最长的公共子序列问题来找到两个文件之间的差异。

DP algorithms are used because in many cases they are the only practical solution. 使用DP算法是因为在许多情况下它们是唯一的实用解决方案。 And besides, there is nothing wrong with them. 而且,它们没有错。

Memory usage: Often, a sliding window can be used to reduce the memory usage dramatically. 内存使用:通常,可以使用滑动窗口来显着减少内存使用。 Fibonacci, when solved using a naive bottom-up DP, requires O(n) memory. 使用天真的自下而上的DP求解时,斐波那契需要O(n)内存。 A sliding window improves this to O(1) memory (I know of the magical constant time solution , but that's beside the point). 滑动窗口可将其改进为O(1)内存(我知道神奇的恒定时间解决方案 ,但这很重要)。

Parallelization: Top-down DPs are often easy to parallelize. 并行化:自上而下的DP通常易于并行化。 Bottom-ups may or may not be. 自下而上可能会也可能不会。 @amit's example (parallelizing longest common subsequence) is a good one, where any given diagonal's tiles can be solved independently as long as the previous diagonals are known. @amit的示例(并行最长公共子序列)是一个很好的例子,只要已知先前的对角线,任何给定对角线的图块都可以独立求解。

The longest common subsequence problem and Longest common substring problem are sometimes important for analyzing strings [analyzing genes sequence, for example]. 最长公共子 序列问题和最长公共子串问题有时对于分析字符串[例如分析基因序列]很重要。 And they can be solved efficiently using dynamic programming. 并且可以使用动态编程有效地解决它们。

Note you can parallelize this algorithm : you do it in iterations on the diagonals [from left,down to right,up] - so total of 2n-1 iterations. 请注意, 您可以并行化此算法 :在对角线上的迭代中(从左,下到右,上)进行迭代-总共进行2n-1次迭代。 And in every diagonal: each cell does not depend on other cells in this diagonal - so parallelizing can be done here, each thread will have a block of cells in this diagonal. 并且在每个对角线中:每个单元格都不依赖于该对角线中的其他单元格-因此可以在此处进行并行化,每个线程在此对角线中将具有一个单元格块。

Note that data synchronization using this method is also minimal: each thread needs only to transfer data to his "neighboring threads" so it can be done even if the memory is not shared. 请注意,使用此方法的数据同步也是最小的:每个线程仅需要将数据传输到其“相邻线程”,因此即使不共享内存也可以做到。

Also, both problems, as @larsmans mentioned - can use linear space - at each point you only need to "remember" the current + 2 last diagonals, and not the entire matrix. 此外,正如@larsmans提到的,两个问题都可以使用线性空间-在每个点上,您只需要“记住”当前+ 2个最后对角线即可,而不必“记住”整个矩阵。

Another common problem that is solved using dynamic programming is polynomial interpolation . 使用动态规划解决的另一个常见问题多项式插值 The interpolation can be effieciently done using Newton Interpolation , which first needs to calculate the divided differences - which is built using dynamic programming. 可以使用牛顿插值有效地完成插值牛顿插值首先需要计算划分的差 -这是使用动态编程构建的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM