在旧游戏时代,由于在旧CPU中计算这些值的速度缓慢,我们习惯于拥有一个预先计算的sin和cos,...等值的查找表。
这被认为是一种动态编程技术吗?或动态编程必须解决一直计算或排序的递归函数?
更新: 在动态编程中,关键是要有一个memoization表,这是sin,cos查找表的解决方案,那么该技术的真正区别是什么?
答案 0 :(得分:4)
我会说你在问题中看到的不是动态编程。 Dynamic programming更多的是通过解决较小的子问题来解决问题,并创建从较小的子问题中解决问题的方法。
您的情况看起来更像memoization。
对我而言,如果您的问题是计算cos N
并且您有cos i
,cos 0
数组计算cos 1
,则可以将其视为DP,... ,cos i - 1
,因此您计算cos 1
,sin 1
并运行i从0到N的计算。
可能有人会纠正我:)
关于dynamic programming
与divide-and-conquer
范例的区别,还有一些有趣的引用:
问题必须具备两个关键属性 动态规划适用:最优子结构和 重叠的子问题。如果问题可以通过组合解决 该策略是非重叠子问题的最优解 相反,称为“分而治之”。这就是mergesort和 quicksort不属于动态编程问题。
答案 1 :(得分:4)
动态编程是一种编程技术,通过将其分解为较小的问题来解决难题,这些问题不是独立的(这很重要!)。
即使你可以从cos i -1计算cos i,这仍然不是动态编程,只是递归。
动态编程经典示例是背包问题:http://en.wikipedia.org/wiki/Knapsack_problem
你想填充一个大小为W的背包,有N个物体,每个物体都有它的大小和价值。 既然你不知道哪个对象的排列最好,你就“试试”每个人。
递归方程式如下:
OPT(m,w) = MAX ( OPT(m-1, w), //if I don't take this object
OPT(m-1, w - w(m)) //If i take it
添加初始案例,这就是您解决问题的方法。当然,您应该构建解决方案,从m = 0开始,w = 0并迭代直到m = N且w = W,以便您可以重复使用先前计算的值。
使用这种技术,你可以找到最佳的物体组合,只需N * W时间就可以进入背包(当然,这不是输入大小的多项式,否则P = NP,没人想要!)而不是指数的计算步骤。
答案 2 :(得分:0)
不,我不认为这是动态编程。由于计算能力有限,正弦和余弦的值作为预先计算的值馈送,就像其他数值常数一样。
对于动态编程技术中要解决的问题,存在许多基本条件。其中一个重要条件是我们应该能够将问题分解为递归可解决的子问题,其结果可以将这些子问题用作查找表来替换递归中的更高链。所以这是递归和记忆。
有关详细信息,请参阅维基百科链接。 http://en.wikipedia.org/wiki/Dynamic_programming