第十六章 贪心算法
来源:互联网 发布:山人教育模型源码 编辑:程序博客网 时间:2024/05/19 23:18
def:贪心算法是一种以局部最优最优选择以期求得全局最优解得算法。
16.1活动选择问题
求一个活动选择问题的域中求最大兼容活动子集。
活动选择问题具有最优子结构:解中若包含活动ak,s.t. S[...k]和S[k+1...]都为最大兼容活动子集
若用c[i,j]来表示S[i...j]的大小则有递归公式:
由此可以通过动态规划方法求解活动选择问题的最优解。
若注意到此问题的一个性质,则可以只需要遍历一遍所有活动采用贪心选择而求得最优解。
贪心选择的是S中结束时间最早的活动。实现如下:
""" 因为 f由小到大排序,所以必然包含第一个活动"""def RECURSIVE_ACTIVITY_SELECTOR(s, f, k, n): m = k + 1 while m < n and s[m] < f[k]: m = m + 1 if m < n: ai = [m] a = RECURSIVE_ACTIVITY_SELECTOR(s, f, m, n) if a != None: ai.extend(RECURSIVE_ACTIVITY_SELECTOR(s, f, m, n)) return ai else: return Nonedef GREEDY_ACTIVITY_SELECTOR(s,f): n = len(s) a = [1] k = 1 for m in range(2, n): if s[m] >= f[k]: a.append(m) k = m return a if __name__ == "__main__": s = [0,1,3,0,5,3,5,6,8,8,2,12] f = [0,4,5,6,7,9,9,10,11,12,14,16] a = RECURSIVE_ACTIVITY_SELECTOR(s,f,0, len(s)) print(a) a = GREEDY_ACTIVITY_SELECTOR(s, f) print(a)
所有的贪心算法问题都有一个对应的动态规划解法。对含有某些特性的动态规划问题,我们用贪心策略,每一步求局部的最优解而最后得到一个最优解。为了保证可以实施贪心策略和贪心算法正确我们需要证明以下三点:
贪心选择性质:对比与动态规划问题我们总是依赖子问题的最优解来构造出问题的最优解,而贪心选择只考虑局部最优,而不依赖于子问题的解。故贪心算法由上而下的分解子问题,而动态规划算法由底向上的求解所有子问题。
所以我们必须要证明局部最优能生成全局最优解,既将问题分解为一个局部最优解和包含最优解的子问题。
通过以上分析0-1背包问题不可以使用贪心算法求解,而分数背包问题可以是用贪心算法求解。
16.3赫夫曼编码
对于定长编码的文件的压缩,使用变长编码既使用短编码表示出现概率高的字符,使用长编码表示出现概率低的字符,以取得对定长编码的优势。为了保证编码的唯一性,我们使用前缀码的特性来简化编解码的过程。文件的最优编码方案就是一棵满二叉树,优于非满二叉树的定长编码:
我们使用HUFFMAN来构造满二叉树:
此过程中使用贪婪策略每次以集合中概率最低的两个对象作为叶子构造一棵子树,通过如下两个引理证明贪心策略有效:
16.4 拟阵和贪心算法
加权的拟阵,可以用贪心算法求解,求解与正确性的证明如下(其实就是动态规划原理中的剪切-粘贴技术证明和定义)
16.5用拟阵求解任务调度问题
def QUICKSORT(A, p, r): if p < r: q = PARTITION(A, p, r) QUICKSORT(A, p, q-1) QUICKSORT(A, q+1, r)def PARTITION(A, p, r): x = A[r][1][0] i = p for j in range(p, r): if A[j][1][0] <= x: temp = A[i] A[i] = A[j] A[j] = temp i = i + 1 temp = A[i] A[i] = A[r] A[r] = temp return idef SCHEDULED(S): A = [] B = [] for i in range(0, len(S)): A.append(S[i]) n = len(A) if n > A[n-1][1][0]: m = 0 w = A[0][1][1] for j in range(1, n): if A[j][1][1] < w: m = j w = A[j][1][1] b = A.pop(m) B.append(b) return A, Bif __name__ == "__main__": S = [(1,(4,70)), (2,(2,60)), (3,(4,50)), (4,(3,40)), (5,(1,30)), (6,(4,20)), (7,(6,10))] QUICKSORT(S, 0, len(S)-1) print(S) A,B = SCHEDULED(S) print(A) print(B)
习题解答
- 第十六章 贪心算法
- 算法导论第十六章--贪心算法
- 算法导论学习笔记-第十六章-贪心算法
- 活动选择问题(算法导论第十六章贪心算法)
- 算法导论第十六章-贪心算法-Cpp代码实现
- 算法导论第十六章贪心算法-0-1背包问题
- 算法导论 第十六章:贪心算法之单任务调度问题
- 算法导论第十六章贪心算法-思考题16-1找零问题
- 算法导论第十六章
- 算法导论第十六章习题16.1-2
- 第四章 贪心算法
- 第十六周算法题
- 第16章 贪心算法
- 第16章 贪心算法
- 第 16 章 贪心算法
- 第十六章
- 第十六章
- 第十六章
- android自动更新功能
- Permutations II [Leetcode 解题报告]
- 使用API网关构建微服务
- iOS 支付宝详细集成总结
- MyEclipse项目上有红色感叹号
- 第十六章 贪心算法
- SCRIPT5007: 无法获取未定义或 null 引用的属性“id”
- Docker与传统虚拟化的差别
- Spring MVC with Maven - java.lang.ClassNotFoundException: org.springframework.web.servlet.Dispatcher
- js jquery提交form表单的方式
- Android SQlite使用实践Demo
- UIViewContentMode各类型效果
- 经验
- JAVA AIO BIO NIO