算法与数据结构-贪心算法及背包问题解决
来源:互联网 发布:服务网络占用硬盘 编辑:程序博客网 时间:2024/06/01 08:37
序言
五大常用算法包括:回溯法 + 贪心算法 + 动态规划 + 分治法 + 分支限界法
之前已经介绍过回溯法及其在八皇后问题的应用。本文介绍贪心算法及其常见应用场景。
贪心算法
- 贪心算法的基本原理
问题求解时,不是从全局最优解来考虑,而是通过求解局部最优解来产生全局最优解或全局最优解的近似解。概念要点: 1. 局部最优解 2. 无后效性,即不可回溯
贪心算法的特性:所求解的问题一般具有两个特性
[1] 贪心选择性质:整体最优可以通过一系列局部最优的选择来达到。
- 贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。
[2] 最优子结构性质:一个问题的最优解已经包含了其子问题的最优解。
- 因此可以依次解决其子问题得到原问题的解
贪心算法的基本思路
- 建立数学模型
- 问题分成若干子问题
- 子问题求解得到子问题的局部最优解(以贪心选择开始)
- 子问题局部最优合成原问题的一个解
贪心算法使用的要点
问题是否可用贪心算法求解:经验判断,适当证明
- 贪心算法适用范围窄,很多时候需要根据经验决定是否选择贪心算法
- 通过数学归纳法进行证明,利用贪心选择性质和最优子结构性质
- 贪心标准的选择
- 很重要,标准选择不好很可能导致解题失败
- 在选择贪心标准时,我们要对所选的贪心标准进行验证才能使用,不要被表面上看似正确的贪心标准所迷惑
与动态规划问题的区别
- 相似:均通过递推实现,均具有最优子结构性质,均无后效性
- 区别:
- 贪心算法每一步的最优解一定包含上一步最优解。上一步最优解不做保留
- 动态规划全局最优一定包含某个局部最优,但不一定包含前一个局部最优。需要记录之前所有最优解
贪心算法常见应用场景
- 公共资源争用的活动安排
- 教室不同时间段活动安排
- 公共资源争用的活动安排
- 背包问题
- 不是”0-1背包问题“
- 背包问题
- 最优装载问题
- 与背包问题类似
- 最优装载问题
- 钱币找零问题
- 最少纸币张数支付K元
- 钱币找零问题
贪心算法应用举例
以背包问题为例简单举例
问题描述
背包问题:有一个背包,背包容量是M=150。有7个物品,物品可以分割成任意大小。要求尽可能让装入背包中的物品总价值最大,但不能超过总容量。
物品 A B C D E F G
重量 35 30 60 50 40 10 25
价值 10 40 30 50 35 40 30贪心标准
- [1] 先把价值高的装进去:这样重量消耗太快,不利于总体价值的增长
- [2] 先把重量小的装进去:这样能保证重量有效增长,但价值不能有效增长
- [3] 先把价值重量比最大的装进去:按物品权重排序,实现重量和总价值的有效增长
代码(C)
#include <stdio.h>#define true 1#define false 0typedef struct pack_node{ int weight; int value; float value2weight; //价值重量比 char flag;}packNode;int main(){ int Weight[7] = {35, 30, 60, 50, 40, 15, 20}; int Value[7] = {10, 40, 30, 50, 35, 40, 30}; packNode back_pack[7]; int i = 0; for (; i < 7; i++) { back_pack[i].weight = Weight[i]; back_pack[i].value = Value[i]; back_pack[i].flag = false; back_pack[i].value2weight = (float)((float)(Value[i]) / (float)Weight[i]); } int allWeight = 0; int allValue = 0; float max = 0.0; //value / weight最大比值 char markArr[7] = {0}; int j, eleFlag; float portion; while (allWeight < 150) { j = 0; max = back_pack[j].value2weight; while (j < 7) { if (back_pack[j].value2weight > max && back_pack[j].flag == false) { max = back_pack[j].value2weight; eleFlag = j; } j++; } back_pack[eleFlag].flag = true; allWeight += back_pack[eleFlag].weight; allValue += back_pack[eleFlag].value; markArr[eleFlag] = 1; if (allWeight > 150) { portion = (back_pack[eleFlag].weight - (allWeight - 150)) / (float)back_pack[eleFlag].weight; printf("第%d个物品选取:%.1f\n", eleFlag + 1, portion); } } int k = 0; printf("取出物品标号如下:"); for (; k < 7; k++) printf("%d%c",markArr[k], k == 6 ? '\n' : ' '); return 0;}
Acknowledgements:
http://blog.csdn.net/liufeng_king/article/details/8709005
http://blog.csdn.net/liufeng_king/article/details/8711928
http://blog.csdn.net/qfikh/article/details/51959226
http://blog.csdn.net/qq_23100787/article/details/50490658
2017.09.14
阅读全文
0 0
- 算法与数据结构-贪心算法及背包问题解决
- 算法与数据结构 - 贪心算法
- 数据结构与算法学习之路:背包问题的贪心算法和动态规划算法
- 数据结构(C#)-- 贪心算法解决背包问题
- 算法与数据结构-背包问题
- 算法设计与分析 普通背包 贪心
- 贪心算法 - 背包问题
- 贪心算法----背包问题
- 【贪心算法】:背包问题
- 贪心算法-背包问题
- 贪心算法 背包问题
- 贪心算法-背包问题
- 【贪心算法】背包问题
- 贪心算法-背包问题
- 贪心算法--背包问题
- 背包问题-贪心算法
- 数据结构之贪心算法(背包问题的思考)
- 数据结构之贪心算法(背包问题的思考)
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛
- 回忆自己的大学---黑龙江科技大学
- 远程过程调用(RPC)详解(发展历史)
- 【C++】【学习笔记】向自定类中添加 combine 和 isbn 成员
- 打字母游戏+贴图技术
- 算法与数据结构-贪心算法及背包问题解决
- 字符串
- 计算机设计思想 —— 代理(proxy)
- redis集群操作
- vb.net 教程 20-3 控制Ie浏览器 4
- Apache Storm 官方文档 —— Trident 教程 原文链接 译者:魏勇 Trident 是 Storm 的一种高度抽象的实时计算模型,它可以将高吞吐量(每秒百万级)数据输入、有状
- 常用易混的输入输出函数用法
- Spring面试60题
- 【Oracle】Clob字段读取,写入,更新