算法与设计技巧——贪婪算法

贪婪算法的相关定义

贪婪算法的定义:贪婪算法分阶段地工作,可认为所作决定是好的,而不考虑将来的后果,一般来说,这意味着选择的是某个局部的最优,当算法停止时,我们希望局部最优就是全局最优。如果是这样的话,那么算法就是正确的;否则算法得到的是一个次最优解。

作业调度问题

单处理器情况

作业调度问题是解决N个作业平均完成的时间(N个作业的平均完成时间是指作业的等待时间加执行时间的总和除以N)最小化,我们假设整个这一节使用非预占调度:一旦开始一个作业,就必须把作业运行到完成为止
完成N个作业的总代价为:C=Σ(N-k+1)Tk=(N+1)ΣTk-Σk·Tk(其中Tk为第K个作业的执行时间)
上述方程中第一项与作业的排序无关(因为他就是所有作业执行时间的总和乘以一个系数),第二项求和影响到了总开销,即作业的执行顺序影响到了总开销。所以作业按照最小运行时间最先安排的调度是所有调度方案中最优的
上述结果指出为什么操作系统调度程序一般把优先权赋予那些更短的作业的原因

多处理器情况

我们可以把问题扩展到多个处理器的情形,我们还是有作业N个,另外处理器个数为p个,不失一般性,我们假设作业是有序的,最短的先运行
解决多处理器情形的算法是按照顺序开始作业,处理器之间轮换分配作业。

Huffman算法

哈夫曼算法可以描述为:算法对一个由树组成的森林进行,一棵树的权等于它的树叶的频率的和,任意选取最小权的两棵树T1和T2,并任意形成以T1和T2为子树的新树,将这样的过程进行C-1次。在算法的开始存在C棵单节点树——每个字符一棵,在算法结束时得到一棵树,这棵树就是最优哈夫曼编码树

  1. 哈夫曼树:又称最优二叉树,它是n个带权叶子节点构成的二叉树中,带权路径长度WOL最小的二叉树
  2. 二叉树的性质有以下几点:
  • 性质1:在二叉树的第i层上至多有2^(i-1)个节点
  • 性质2:深度为k的二叉树至多有2^k-1个节点
  • 在这里插入图片描述
哈夫曼算法正确性证明:

哈夫曼算法正确性的证明主要围绕两点:

  1. 代价最小两个节点的在最深层次
  2. 这两个节点为兄弟节点

首先我们先明确哈夫曼算法是指构建最小带权路径的二叉树,构建方法是采用贪心算法,每次取两个权值最小的子树作为新树的左右子树,最后得到的便是最优二叉树(即哈夫曼树)
首先证明第一点,采用反证法:
在这里插入图片描述
假设在最优二叉树中A,B两个节点不是代价最小的,如A>C>B,假设C在第n层,A在第n+1层,那么A和C交换后代价会变化[A(n+1)+C]-[C(n+1)+A]=A-C>0,说明如果最小代价的两个节点不在最深层次的话就不满足最优二叉树

接着证明第二点,也是采用反证法
首先假定 T 是一颗最优树,T这棵树的权值记为W(T)。最小权值的两个A,B一定在最下层,对应的路径权值分别是 Wa, Wb。
倘若删除A和B,A和B的父节C成为一个叶子节点。此时新树为 T*,W(T) = W(T*) +Wa + Wb;
假设T* 不是最优树,则必定有最优树 T11(T11是包含C的树)。因为T11是最优树,所以必定有W(T11) <= W(T*) ,
此时若把T11中的C展开成A和B,形成新树 T1 ,W(T1) = W(T11) + Wa + Wb;
因为T1和T都为最优二叉树,故两者的权值应该相同,即 W(T*) +Wa + Wb=W(T11) + Wa + Wb,即W(T*)=W(T11),与假设所得结论所矛盾,故证明完成

发布了67 篇原创文章 · 获赞 0 · 访问量 1395

猜你喜欢

转载自blog.csdn.net/clearLB/article/details/104297108