一、算法设计
1、很多时候,对于数据结构中用到的算法都是一些具体的实现,一些具体的实例,这里讨论的是算法设计的一般性方法。
二、贪婪算法
1、在每一个节点,选择局部最优的结果。以局部最优表示全局最优解。在通常情况下,这都是适用的,如果局部最优代替不了全局最优,
得到的就是一个次最优解。
2、如果不要求绝对最佳答案,那么有时候用简单的贪婪算法生成近似答案,而不是使用一半说来产生准确答案所需要的复杂算法。
3、贪婪算法的几个应用,包括简单的调度问题,文件压缩,最短路径等。
4、实际上,所有的调度问题或者是NP完全的,或者是贪婪算法可解的。
5、Huffman算法,可以应用到文件压缩中,采用依次合并最小的权树来生成。
6、近似装箱问题:
将N个物品装到M个箱子里。
a、存在使得任意联机装箱算法至少使用4/3最优箱子数的输入。
b、联机最佳适合算法在完全随机的情绪下,得到的箱子比最优装箱方法多约2%,在许多情况下,这是完全可以接受的。
c、使用脱机算法,可以观察全部物品后再算出答案,可以先排序,通过改进的首次适合非增算法可以 使得箱子数不超过最优的4/3倍。
7、贪婪算法在有最优子结构的问题中尤为有效。最优子结构的意思是局部最优解能决定全局最优解。
简单地说,问题能够分解成子问题来解决,子问题的最优解能递推到最终问题的最优解。
三、分治算法
1、分治算法由两部分组成:
分:递归解决较小的问题
治:然后,从子问题的解构建原问题的解。
2、传统上,在正文中至少含有两个递归调用的例程叫做分治算法。典型实例如:归并排序、快速排序等。
3、对于方程:T(N)=2*T(N/2) + O(N),方程的解为O(NlogN)。
4、一些其他实例:
a、最近点问题:对于平面上的N各点,找出最近的两个点。
可以通过计算所有的点距离,然后都比较之,如此将花费O(N*N)。
可以通过分治,对x进行排序,然后以一个分界线将平面分成两部分,然后分别计算,所得时间复杂度可以为O(N*logN)。
四、动态规划算法
1、动态规划是一种在数学和计算机科学中使用的,用于求解包含重叠子问题的最优化问题的方法。
其基本思想是,将原问题分解为相似的子问题,在求解的过程中通过子问题的解求出原问题的解。
2、性质
a、最优子结构性质。如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质
(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。
b、子问题重叠性质。子问题重叠性质是指在用递归算法自顶向下对问题进行求解时,每次产生的子问题并不总是新问题,
有些子问题会被重复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只计算一次,然后
将其计算结果保存在一个表格中,当再次需要计算已经计算过的子问题时,只是在表格中简单地查看一下结果,从而
获得较高的效率。
3、贪婪算法与动态规划的不同在于它每对每个子问题的解决方案都做出选择,不能回退。动态规划则会保存以前的运算结果,并 根据以前的结果对当前进行选择,有回退功能。
4、实例:
斐波那契数列
背包问题
五、随机化算法
1、产生随机数的最简单的方法:线性同余数发生器。
Xi+1 = AXi mod M
建议取值:M=2^31 - 1 = 2147483647, A=48271
2、应用:
跳跃表
素性测试
六、回溯算法
1、在许多情况下,回溯算法相当于穷举搜索的巧妙实现,但性能一般不理想。不过,情况并不总是如此,即使如此,在某些情形下它
相比蛮力穷举搜索,工作量也有显著的节省。
2、当然,性能是相对的:对于排序而言,O(N^2)的算法是相当差的,但对旅行售货员(或任何NP完全)问题,O(N^5)算法则是
里程碑式结果。
3、一些实例:
收费公路重建问题
博弈
七、总结
1、熟悉了数据结构之后,要从理论上再理解算法设计,从具体抽象出一般的设计方法。
2、很多算法都和数学结合的比较紧密,需要使用数学方法来证明其可行性与不可行性,使用数学方法来分析时间复杂度和空间复杂度,
使用很多数学方面的成果。
3、所以说,数学是科学的根本,当然也包括了计算机科学。