这是对算法新的感悟:
算法是一个数学概念,在计算机科学中算法必须是可行的,必须满足这两条要求。
1,该算法可以被证明,能求出问题的解。
2,该算法是可行的,就是运行时间和占用内存是有限的。
这才是一个合格的算法,在满足以上条件的基础上能用最小内存或者最短时间解决问题,就能称之为最优算法。
数学思维的培养不是一朝一夕的事情,需要长期锻炼。
动态规划算法的应用场景是一个问题的最优解可以分解为子问题的最优解。
判断一个问题满不满足这种性质需要一定的数学功底。这里是动态规划的本质特点。最常见的数学方法是数学归纳法。
从以下几个例子来学习运用动态规划算法。
装配车间路线选择问题
动态规划能处理那些通过枚举所有值所不能处理的问题。这里有一个隐含的条件,子问题之间必须是独立的,
一个子问题的解决对另外一个子问题的解决不具有任何影响。必须符合这个条件才能使用动态规划算法。
1.描述最优解的结构,显示描述子过程最优解的结构,就像是装配车间问题的两条生产线s1,s2,分别有n个装配点,
要计算出通过s1j和s2j这两个谁的需要时间最短,其实就是计算出到达s1j或者s2j之前的最短时间,也就是完成s1,j-1或者s2,j-
1的最短时间,所以子问题里面有四条路径,s1j到s1j-1,s1j到s2j,s2j到s1j-1,s2j到s2-1,
计算这四条路径最短的一个就是这个问题的子问题。
2,递归定义最优解的值。就是有s1到s2最优解,然后从s2到s3最优解。
3,然后自低向上就算最优解的值,跟我想象的一样。
4,最后求出问题的解。
矩阵的乘法问题
1,子问题的最有解是找出计算次数的最少的矩阵先相乘,把得到的矩阵放到原矩阵中,然后递归调用就行了。 怎样证明这个想法的正确性呢?这个比较好证明,因为矩阵相乘的次数是确定的,我们每次执行的乘法是运行次数最小的。 但是并不好证明这是一个最优的算法,也许存在比这个更好的算法。 js代码如下,用数组的数组表示矩阵元素的个数,输出矩阵相乘的顺序。
能力有限有好的写法可以评论留言,谢谢。
最长公共子序列
这是我刚开始碰到这个问题的思考:最长公共子序列我并没有思考出答案,还是看书得到的。 这是我的思维模式问题,当时思考的是用短的和长的作比较, 找出每一个比较的相同的序列,然后可以得到最长子序列,这种方式当然可以做,可惜不是动态规划,我并没有想到将问题分解。 我想到另外一种方法也是根据课本上的启发,假如有两个字符串序列a1,a2, 那么一个字符串横向 排列,一个字符串竖直排列,这样就可以组成一个二位数组,果字符相同那么就将该数组标成1,如果不同就标称0, 该数组记作S,加入Sij = 0;那么就排查S(i+1)(j+1),如果他等于1,就继续排查直到等于0,或者结束,记录这次排查的长度。 然后接着向后排查。不不不,这样计算有问题,这就默认了最长子序列必须从第一个开始,也有可能最长子序列 是从第二个开始的,这种算法是错误的。 我的概念搞混了,最长公共子序列和总长公共字符串认为是一个概念。这次明白了概念再去看看就行了。按照这个思考方式产生了下面的代码:
这个方法即笨蛋又错误,他不是建立在数学论证的基础上大,而是根据感觉写的。下面是正确的分析:
这其实还是一个分解成子问题的数学归纳法的问题。这并不是一个很难的问题,相反这是非常简单的。
课本上已经尽可能向你讲清楚了,可是我非要用惯用的思维去理解。不用递归成子问题的思想去解决。做出算法的过程是一个方法论。
原来好多事情是有方法论的。
如果Sk是字符串A1m和A2n的最长子序列,
假如 Sk==A1m==A2n 那么必有Sk-1是A1m-1和A2n-1的最长子序列;
假如 Sk!= A1m 那么必有Sk是A1m-1和A2n的最长子序列;
假如 Sk!= A2n 那么必有Sk是A1m和A2n-1的最长子序列;
用Cij表示A1m和A2n的最长子序列。算法示意图如下
let m = A1m.length,n= A2n.length;
for(let i from 0 to m)
for(let j from 0 to n){
if(A1m[i] == A2n[j]){
Cij = Ci-1,j-1 + 1;
}
if(Cij-1<Ci-1,j) Cij =Ci-1,j
else Cij =Ci,j-1
}
为什么我能到这里就不会了呢?因为我不知道比较到最开始的最初条件, 所以我的思想就下意识的回避了这个问题。到原来熟悉的道路上去。这不就是一个反向递归吗,递归的终点直到某一项是i==0,或者j==0; 如果这样直接求解会怎么样呢?我不能开始就反向求解,因为我没有最长子序列。倒叙求解正序计算。最后一步做算法优化就行了。 要让我的思维用这种方式重新跑即便也许就行了。最终的计算方法如下:
勤能补拙这个话是正确的,人和人的差别是很小的,思维模式决定行为模式,人的潜意识思维是懒惰的,遇到不好解决的问题潜意识就会自动跳转到熟悉的道路上来,自我提升的过程就是把不熟悉的道路多走几遍变成熟悉的道路,思维路径多了,行为模式就改变了。