【精选】贪心算法的应用

合集下载

贪心算法在优化问题中的运用

贪心算法在优化问题中的运用

贪心算法在优化问题中的运用贪心算法(Greedy Algorithm)是一种常用的算法思想,它在解决一些优化问题时具有很高的效率和实用性。

贪心算法的核心思想是每一步都选择当前状态下最优的解决方案,以期望最终能够得到全局最优解。

在实际应用中,贪心算法常常被用来解决一些最优化问题,如最短路径问题、背包问题、任务调度等。

本文将介绍贪心算法在优化问题中的运用,并通过具体案例来说明其应用场景和解决方法。

一、贪心算法的基本原理贪心算法是一种在每一步选择当前状态下最优解决方案的算法思想。

它与动态规划不同,贪心算法并不会保存之前的计算结果,而是根据当前状态做出最优选择。

贪心算法的优势在于简单、高效,适用于一些特定类型的问题。

贪心算法的基本原理可以总结为以下几点:1. 每一步都选择当前状态下的最优解决方案;2. 不考虑未来的结果,只关注当前状态的最优选择;3. 最终期望通过每一步的最优选择达到全局最优解。

二、贪心算法在优化问题中的应用1. 最短路径问题最短路径问题是图论中的经典问题,贪心算法可以用来解决一些简单的最短路径问题。

例如,在无权图中,从起点到终点的最短路径可以通过贪心算法来求解,每次选择距离最近的节点作为下一步的目标节点,直到到达终点为止。

2. 背包问题背包问题是一个经典的优化问题,贪心算法可以用来解决一些特定类型的背包问题。

例如,在分数背包问题中,每种物品可以取任意比例,贪心算法可以按照单位价值最高的顺序选择物品放入背包,直到背包装满为止。

3. 任务调度问题任务调度问题是一个常见的优化问题,贪心算法可以用来解决一些简单的任务调度问题。

例如,在单处理器任务调度中,每个任务有一个开始时间和结束时间,贪心算法可以按照结束时间的先后顺序对任务进行调度,以最大化处理器的利用率。

三、案例分析:活动选择问题活动选择问题是一个经典的优化问题,通过贪心算法可以高效地解决。

问题描述如下:假设有n个活动,每个活动都有一个开始时间和结束时间,活动之间不能交叉进行,问如何安排活动才能使参加的活动数量最多。

贪心算法原理及应用

贪心算法原理及应用

贪心算法原理及应用随着人工智能技术的不断发展,算法的种类也越来越多,其中贪心算法作为一种最基础的算法,也在不断优化和升级。

本文将简要介绍贪心算法原理及其应用,探讨贪心算法的优劣和适用场景。

一、贪心算法原理贪心算法是一种常见的优化算法,它的基本思想是:在每一步选择中都采取当前状态下最优的选择,从而希望最终得到全局最优的解。

贪心算法在每一步选择中都依赖于以前的选择结果,但不依赖于将来的选择结果。

这种贪心选择性质是该算法能达到最终全局最优解的保证。

然而,即使每个局部最优的选择都是正确的,但最终的全局最优解并不一定会得到,因此贪心算法不一定能得到全局最优解,但是在实际问题中,贪心算法通常可以得到非常接近最优解的结果。

二、贪心算法应用1.最小生成树最小生成树是图论中的一个经典算法问题,它可以用贪心算法来解决。

在给定一个带权无向图时,我们需要找到一棵生成树,使得生成树所有边的权值之和最小。

Prim算法和Kruskal算法都是基于这一思想建立的。

2.背包问题背包问题是一种经典的动态规划问题,也可以用贪心算法来解决。

在背包问题中,我们需要找到一种最佳的方案,使得放入背包的物品的总价值最大。

3.活动安排在一组活动中,每个活动都有一个开始时间和结束时间。

如何安排这些活动,使得可以安排的最多?可以用贪心算法进行解决。

三、贪心算法的优劣1.优点优点是:简单,易于实现;对于一些问题可以快速得到答案。

2.缺点缺点是:贪心算法不能保证得到全局最优解,只能得到最终结果接近最优解的结果。

在一些问题中会出现无解的情况。

此外,贪心算法需要根据实际问题进行调整,否则可能会得到错误的答案。

3.适用场景对于一些特殊的问题,贪心算法通常可以得到非常好的效果。

例如上文提到的最小生成树、背包问题和活动安排等等。

在这些问题中,贪心算法可以得到接近最优解的结果。

但是,在一些问题中,贪心算法的结果会偏离真实结果。

四、结语贪心算法是一种简单而实用的算法,它在很多实际问题中都有广泛的应用。

列举用贪心算法求解的经典问题

列举用贪心算法求解的经典问题

列举用贪心算法求解的经典问题贪心算法是一种简单而高效的问题求解方法,通常用于求解最优化问题。

它通过每一步选择当前状态下的最优解,最终得到全局最优解。

贪心算法的核心思想是:每一步都做出一个局部最优的选择,并认为这个选择一定可以达到全局最优。

以下是一些经典问题,可以用贪心算法求解:1. 零钱兑换问题(Coin Change Problem):给定一些不同面额的硬币和一个目标金额,找到最少的硬币数量,使得硬币总额等于目标金额。

贪心算法可以按照硬币的面额从大到小进行选择,每次选择尽量大面额的硬币。

2. 区间调度问题(Interval Scheduling Problem):给定一些区间,找到最多的不相交区间。

贪心算法可以按照区间的结束时间进行排序,每次选择结束时间最早的区间,确保选择的区间不重叠。

3. 分糖果问题(Candy Problem):给定一个数组表示每个孩子的评分,要求给这些孩子分糖果,满足以下要求:每个孩子至少分到一个糖果,评分高的孩子要比相邻孩子分到的糖果多。

贪心算法可以从左到右进行两次遍历,分别处理评分递增和评分递减的情况。

4. 跳跃游戏问题(Jump Game Problem):给定一个非负整数数组,表示每个位置的最大跳跃长度,判断是否能从第一个位置跳到最后一个位置。

贪心算法可以记录当前能够到达的最远位置,并且更新为更远的位置。

5. 任务调度器问题(Task Scheduler Problem):给定一串任务,每个任务需要一定的冷却时间,要求以最短的时间完成所有任务。

贪心算法可以按照出现次数进行排序,优先执行出现次数最多的任务,并在冷却时间内执行其他任务。

6. 区间覆盖问题(Interval Covering Problem):给定一些区间,找到最少的区间数,使得它们的并集覆盖了所有输入区间。

贪心算法可以根据区间的起始位置进行排序,每次选择最早结束的区间,并将它添加到最终结果中。

以上仅是一些经典问题的例子,实际上还有很多问题可以用贪心算法来求解。

贪心算法几个经典例子c语言

贪心算法几个经典例子c语言

贪心算法几个经典例子c语言1. 零钱兑换问题题目描述:给定一些面额不同的硬币和一个总金额,编写一个函数来计算可以凑成总金额所需的最少的硬币个数。

如果没有任何一种硬币组合能够凑出总金额,返回 -1。

贪心策略:每次选择面额最大的硬币,直到凑出总金额或者无法再选择硬币为止。

C语言代码:int coinChange(int* coins, int coinsSize, int amount){int count = 0;for(int i = coinsSize - 1; i >= 0; i--){while(amount >= coins[i]){amount -= coins[i];count++;}}return amount == 0 ? count : -1;}2. 活动选择问题题目描述:有 n 个活动,每个活动都有一个开始时间和结束时间,选择一些活动使得它们不冲突,且能够参加的活动数最多。

贪心策略:每次选择结束时间最早的活动,直到所有活动都被选择或者无法再选择为止。

C语言代码:typedef struct{int start;int end;}Activity;int cmp(const void* a, const void* b){return ((Activity*)a)->end - ((Activity*)b)->end;}int maxActivities(Activity* activities, int n){qsort(activities, n, sizeof(Activity), cmp);int count = 1;int end = activities[0].end;for(int i = 1; i < n; i++){if(activities[i].start >= end){count++;end = activities[i].end;}}return count;}3. 跳跃游戏题目描述:给定一个非负整数数组,你最初位于数组的第一个位置。

贪心算法通过每次选择局部最优解来达到全局最优

贪心算法通过每次选择局部最优解来达到全局最优

贪心算法通过每次选择局部最优解来达到全局最优贪心算法是一种常用的解决优化问题的算法。

它通过每次选择局部最优解来达到全局最优的目标。

在本文中,我们将介绍贪心算法的原理、应用场景以及优缺点。

一、原理贪心算法的基本原理非常简单:每一步都选择当前状态下的局部最优解,最终得到的结果就是全局最优解。

贪心算法不考虑过去的选择对未来的影响,只关注眼前的最佳选择。

二、应用场景贪心算法在各个领域都有广泛的应用,下面我们将以几个常见的实际问题来说明。

1. 图的最小生成树问题在一个连通无向图中,找到一个包含所有节点且权值最小的无回路子图,这个问题称为最小生成树问题。

贪心算法可以通过每次选择权值最小的边来逐步构建最小生成树。

2. 分糖果问题有一组孩子和一组糖果,每个孩子有一个需求因子和每个糖果有一个大小。

当糖果的大小不小于孩子的需求因子时,孩子可以获得该糖果。

目标是尽可能多地满足孩子的需求,贪心算法可以通过给每个孩子分配满足其需求因子的最小糖果来达到最优解。

3. 区间调度问题给定一个任务列表,每个任务有一个开始时间和结束时间。

目标是安排任务的执行顺序,使得尽可能多的任务能够被完成。

贪心算法可以通过选择结束时间最早的任务来实现最优解。

以上只是一些贪心算法的应用场景,实际上贪心算法可以用于解决各种优化问题。

三、优缺点1. 优点①简单:贪心算法的思路相对简单,容易理解和实现。

②高效:由于只考虑局部最优解,贪心算法的时间复杂度较低,通常能够在较短的时间内得到一个接近最优解的结果。

③可用于近似求解:由于贪心算法不保证得到全局最优解,但可以用于求解近似最优解的问题。

2. 缺点①不保证全局最优解:贪心算法只考虑眼前的最优选择,无法回溯和修正过去的选择,因此不能保证得到全局最优解。

②局部最优解无法转移:在某些情况下,局部最优解并不一定能够转移到全局最优解,导致贪心算法得到的结果偏离最优解。

③对问题的要求较高:由于贪心算法需要找到适合的局部最优解,因此问题必须具备一定的特殊性,而一些问题无法使用贪心算法解决。

贪心算法的概念和适用条件

贪心算法的概念和适用条件

贪心算法的概念和适用条件什么是贪心算法?贪心算法(Greedy Algorithm)是一种以局部最优解为导向的算法思想,通过每一步选择当前状态下的最佳操作来达到整体最优解的目标。

贪心算法的核心思想是每次都做出当前看来最优的选择,以期望能够达到整体的最优解。

贪心算法通常用于一些问题中,即每一步的选择只依赖于当前状态,而不考虑将来可能出现的情况。

贪心算法的适用条件:1. 贪心选择性质:贪心算法每一步都选择一个当前的最优解,此处的“最优”指的是局部最优。

这种最优选择可以确保问题能够被拆解,并且进行下一步求解。

2. 最优子结构性质:当问题的整体最优解能够通过局部最优解得到时,可以采用贪心算法求解。

这种情况下,问题的最优解可以由子问题的最优解推导出来。

3. 无后效性:贪心算法选择某一步操作时,只考虑当前状态,不会改变以前的操作,并且不关心未来的操作。

这种无后效性使得贪心算法在实际应用中操作简单、效率高。

贪心算法的基本步骤:1. 确定问题的局部最优解:贪心算法的核心是每一步都选择在当前情况下的最优解。

因此,需要确定问题如何拆解以及如何进行局部最优选择。

2. 定义问题的子问题:根据问题的最优子结构性质,将问题拆解为较小规模的子问题。

子问题应该是原问题的一个更小、更简单的实例。

3. 定义贪心选择策略:根据问题的特性,确定当前步骤下的最优选择策略。

这个选择应该是局部最优的,可以在不考虑子问题和整体未来状态的情况下得出。

4. 重复执行步骤2和3,直至求解出全局最优解。

贪心算法的优缺点:贪心算法具有简单易懂、快速高效的特点,适用于许多实际问题。

它可以避免穷举所有可能性,节省了计算时间。

此外,贪心算法常常能够找到近似最优解,尽管不一定能够保证全局最优解。

在实际问题中,近似最优解也往往可以满足实际需求。

然而,贪心算法并非适用于所有问题。

由于贪心算法只考虑当前状态的最优选择,而不考虑未来的影响,因此可能会导致局部最优解与全局最优解不一致。

贪心算法对于NP完全问题的应用

贪心算法对于NP完全问题的应用

贪心算法对于NP完全问题的应用贪心算法是一种常用的算法思想,在很多问题中具有很高的实用性和效率,然而,对于一些高难度的问题,如NP完全问题,贪心算法能否起到很好的应用呢?本文将从贪心算法的基本思想、NP完全问题的定义和特点、以及贪心算法在NP完全问题中的应用方面进行探讨。

一、贪心算法的基本思想贪心算法是一种具体的算法设计思想,是将问题分解为若干个子问题,通过每次选择最优的解决方案,最终得到全局最优解的算法。

贪心算法通常具有如下特征:(1)贪心选择性质:所采取的选取方案必须是具有最优子结构的,即选择一定范围内的最优子问题;(2)无后效性:当前选择与之后的选择无关,即之前做出的选择只关心当前的最优解,而不管之后的怎样变化;(3)子问题的无关性:所作选择只与当前状态有关,与之前或之后状态无关,不受外界干扰。

贪心算法具有较高的效率,并具有通用性,常用于需要快速求解问题的场合。

二、NP完全问题的定义和特点NP问题(Non-deterministic Polynomial problem)是指在多项式时间内验证最优解,但需要超出多项式时间才能找到对应解的问题,这类问题有较高的计算复杂度。

NP完全问题则更具难度,是指所有NP算法都能在多项式时间内进行验证,但却无法在多项式时间内求解的问题。

NP完全问题的典型代表有旅行商问题、背包问题、图着色问题等。

NP完全问题具有以下特点:(1)时间复杂度高;(2)问题规模较大;(3)难以构建正确且高效的算法解决。

三、贪心算法在NP完全问题中的应用贪心算法在NP完全问题中的应用具有一定的限制,部分NP 完全问题不适合使用贪心算法进行求解。

但是,对于一些特定的NP完全问题,贪心算法仍然具有明显的优势,可以实现较高效率和较好表现。

以下是一些贪心算法在NP完全问题中的应用实例:(1)最小生成树问题:该问题即求解一个图的最小生成树。

通过Kruskal算法或Prim算法,使用贪心策略选择当前最短边或顶点,即可快速求解。

贪心算法 思政案例

贪心算法 思政案例

贪心算法思政案例贪心算法是一种常用的解决问题的算法思想,通过每一步的局部最优选择来达到全局最优解。

它通常适用于那些可以通过局部最优选择得到全局最优解的问题。

在思政教育中,贪心算法可以应用于一些案例,通过贪心选择策略来解决问题,提高学生的思政学习效果。

以下是一些与思政教育相关的案例和参考内容,以帮助学生理解贪心算法的应用:案例一:社会责任感的培养在大学生思政教育中,社会责任感是一个重要的素养。

如何培养学生的社会责任感成为教育者关注的问题。

可以构建一个案例:一个学生义工组织查找需要帮助的社区,为每个社区评估一个“帮助指数”,指数高的社区需求多、有困难的帮助,指数低的社区需求少、相对容易帮助。

学生义工组织制定帮助计划时可以利用贪心算法,优先选择帮助指数高的社区,以更有效地发挥有限的义工资源。

参考内容:介绍贪心算法的基本思想,并解释为什么在这个案例中可以适用贪心算法。

同时,提供帮助指数的评判标准和算法设计思路,提醒学生在贪心选择中需综合考虑社区的实际情况和需求。

案例二:环保意识的提升环保意识的培养是思政教育的重要目标之一。

可以设计一个案例:一个学生组织参与清洁行动,清洁的地点有多个,每个地点的垃圾数量不同,清理的难度也不同。

学生组织在制定清理计划时可以采用贪心算法,优先选择垃圾数量多、清理难度小的地点,以达到更好的清洁效果。

参考内容:介绍贪心算法的基本思想,并解释为什么在这个案例中可以适用贪心算法。

对垃圾数量和清理难度的评判标准进行讨论,提醒学生在贪心选择中需综合考虑清洁的实际情况和效果。

案例三:公共资源的分配公共资源的分配是一个重要的社会问题,如何合理分配公共资源是一个关键的决策。

可以构建一个案例:一个学生班级需要安排课外活动,但有限的经费和场地需要合理分配。

学生班级可以利用贪心算法,优先选择经费多、场地条件好的活动方式,以保证活动的质量和效果。

参考内容:介绍贪心算法的基本思想,并解释为什么在这个案例中可以适用贪心算法。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

贪心算法的应用课程名称:算法设计与分析院系:计算机科学与信息工程学院学生姓名:****学号:**********专业班级:********************************** 指导教师:******201312-27贪心算法的应用摘要:顾名思义,贪心算法总是作出在当前看来最好的选择。

也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。

当然,希望贪心算法得到的最终结果也是整体最优的。

虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。

如单源最短路经问题,最小生成树问题等。

在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。

贪心算法求问题一般具有两个重要性质:贪心选择性质和最优子结构性质。

所谓贪心选择性是指所求问题的整体最优解可以通过一系列局部最优解的选择,即贪心选择达到。

这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法主要区别。

当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。

问题的最优子结构性质是该问题可用动态规划算法或贪心算法求解的关键特征。

背包问题是一个经典的问题,我们可以采用多种算法去求解0/1背包问题,比如动态规划法、分支限界法、贪心算法、回溯法。

在这里我们采用贪心法解决这个问题。

关键词:贪心法背包问题最优化目录第1章绪论 (3)1.1 贪心算法的背景知识 (3)1.2 贪心算法的前景意义 (3)第2章贪心算法的理论知识 (4)2.1 问题的模式 (4)2.2 贪心算法的一般性描述 (4)第3章背包问题 (5)3.1 问题描述 (5)3.2 问题分析 (5)3.3算法设计 (5)3.4 测试结果与分析 (10)第4章结论 (12)参考文献 (13)附件 (13)第1章绪论1.1 贪心算法的背景知识贪心算法又叫登山法,它的根本思想是逐步到达山顶,即逐步得最优解,是解决最优化问题时的一种简单但适用范围有限的策略。

“贪心”可以理解为以逐步的局部最优,达到最终的全局最优。

贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择。

一定要注意,选择的贪心策略要有无后向性,即某阶段状态一旦确定以后,不受这个状态以后的决策影响。

也就是说某状态以后的过程不会影响以前的状态,至于当前的状态有关,也称这种特性为无后效性。

已经学会在解的范围可以确定的情况下,可以采用枚举或递归策略,找出所有的结果,一一比较它们,可能在有限的时间内找不到问题的解。

这时可以考虑用贪心的策略,选取那些最可能到达解的情况来考虑。

例如为了使生产某一产品所花费的时间最少,一种贪心的策略就是在生产该产品的每一道工序上都选择最省时的方法。

所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择。

也就是说,不从整体最优上加以考虑,所做出的仅是在某种意义上的局部最优解。

1.2 贪心算法的前景意义贪心算法的主要思想是从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。

当达到某算法中的某一步不能再继续前进时算法停止。

该算法存在问题其一是不能保证求得的最后解是最佳的;其二,不能用来求最大或最小解问题;其三,只能求满足某些约束条件的可行解的范围。

所以贪心算法是解决最优化问题时的一种简单但适用范围有限的策略。

贪心算法无后向性在解的范围可以确定的情况下,可以采用枚举或递归策略,找出所有的结果,一一比较它们,可能在有限的时间内找不到问题的解。

这时可以考虑用贪心的策略,选取那些最可能到达解的情况来考虑。

贪婪算法策略在《数据结构》课程中的算法也有广泛的应用,如霍夫曼树、构造最小生成树的Prim算法和Kruskal算法的决策过程,都是使用的贪婪算法策略。

第2章贪心算法的理论知识2.1 问题的模式对于背包问题。

重量为w1,w2,w3…wn的若干物品和容量为m的背包,物品的价值分别为p1,p2,p3…pn。

要求找出这n个物品的一个子集,使其尽可能是选入背包的物品的价值最大,即:最大化:w1+w2+w3+…+wn<=m时,也就是如果所选取的货物的总重量小于背包容量就全选进去;但出现了w1+w2+w3+…+wn>m时,对物品先进行按单位价值高到低排序,为了不把物品原来的编码打乱,采用一个数组来存放单位价值从大到小的物品的编码即可。

所以就只能选取n个货物中的一部分使其总利润最大。

2.2 贪心算法的一般性描述贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题它能产生整体最优解或者是整体最优解的近似解。

贪心算法的基本思路如下:(1)建立数学模型来描述问题。

(2)把求解的问题分成若干个子问题。

(3)对每一子问题求解,得到子问题的局部最优解。

(4)把子问题的解局部最优解合成原来解问题的一个解。

这就是一个用贪婪算法来解决背包问题课题,我们假设每一种货物都可以分成需要的任意小部分放入背包,要求从中取得最大利润。

因为每一个物品都可以分割成单位块,单位块的利益越大显然总收益越大,所以它局部最优满足全局最优,可以用贪心法解答。

第3章背包问题3.1 问题描述贪心算法解决背包问题:一个商人带着一个能装m千克的背包去乡下收购货物,准备将这些货物卖到城里获利。

现在有n种货源,且知道第i中货物有wi 千克,可获利pi元。

请编写算法帮助商人收购货物,以获取最高的利润。

3.2 问题分析首先,输入物品的个数和背包的容量,再对所有物品的重量累加如果总重量小于背包的容量,就将所有的物品装入背包;如果大于背包的总容量将这些物品按照单位价值从高到低的顺序进行排序,然后进行选择。

并且要求所选物品的最终总量不能超过背包能承受的重量,要求所选的最终方案为最优。

3.3算法设计对于本课题我们可一大致分两种情况:当w1+w2+w3+...+wn<=m时,选取所有物品即可,得到总的价值;当w1+w2+w3+...+wn>m的情况,只能选取一部分货物装入背包,这里假设每一个物品都可以分成任意一小部分,所以利用贪心策略,每次优先选取价值与重量比最大的装入背包,就能获得最高的利润,直到背包刚好装满为止,然后输出必要的数据及结果。

在对物品按单位价值从大到小排列的具体实现可以使用快速排列算法,并用p1[max]=0来标记已经进行排列的物品,这样可以使搜索的项越来越少。

3.3.1算法分析因为每一个物品都可以分割成单位块,单位块的利益越大显然总收益越大,所以它局部最优满足全局最优,可以用贪心法解答。

方法如下:(1)先将单位块收益按从大到小进行排序;(2)初始化背包当前装入量和当前价值;(3)从前到后考虑所有物品:a.如果可以完全放入,当前价值加上物品总价值,背包当前装入量加上物品总体积;b.如果可以部分放进,当前价值加上物品价值*背包剩余体积,以至于背包的剩余体积为0.利用贪心策略解题,需要解决两个问题:(1)确定问题是否能用贪心策略求解;一般来说,适用于贪心策略求解的问题具有以下特点:a. 可通过局部的贪心选择来达到问题的全局最优解。

运用贪心策略解题,一般来说需要一步步的进行多次的贪心选择。

在经过一次贪心选择之后,原问题将变成一个相似的,但规模更小的问题,而后的每一步都是当前看似最佳的选择,且每一个选择都仅做一次。

b. 原问题的最优解包含子问题的最优解,即问题具有最优子结构的性质。

在背包问题中,第一次选择单位质量最大的货物,它是第一个子问题的最优解,第二次选择剩下的货物中单位重量价值最大的货物,同样是第二个子问题的最优解,依次类推。

(2)如何选择一个贪心标准?正确的贪心标准可以得到问题的最优解,在确定采用贪心策略解决问题时,不能随意的判断贪心标准是否正确,尤其不要被表面上看似正确的贪心标准所迷惑。

在得出贪心标准之后应给予严格的数学证明。

3.3.2数据结构在进行算法设计时为了使数据更容易观察和操作,我们需要设定一些必要的数组等变量。

m变量是背包的容量,n是物品的总种类数,pp是装入背包中物品的总价值。

W数组来存放输进来的物品的重量,其下标代表物品的编号;P数组存放每一件物品的价值,同样下标代表物品的编号;P1是P数组的副本是用来在计算中使用的,有可能会改变其中的值;b数组用来存放根据单位价值由大到小排了序的物品的编号;它的下标代表着物品单位价值的大小的次序。

比如:b[1]是单位价值最大的物品的编号。

再定义一个计算装入背包中的物品的总价值,可以在输出结果时在输出选取物品的编码和重量的同时还可以得到总价值。

(1)输入了物品的信息后,对物品的重量累加:for(i=1,s=0;i<=n;i++)//算出物品的总重量s{ printf("物品的编号: %d\n重量: ",i);scanf("%f",&w[i]);printf("价值:");scanf("%f",&p[i]);p1[i]=p[i];s=s+w[i];}(2)如果s<=m,就可以得到问题的解并输出得到的总利润:if(s<=m)//物品的总重量如果小于m则全装入{for(i=1;i<=n;i++)pp+=p[i];printf("选择的结果是:物品的总重量小于背包的容量故全装入背包,得到的总利润是:%f\n",pp);return 0 ;}(3)如果s>m时,用选择排序法对物品按单位价值排序:for(i=1;i<=n;i++){max=1;for(j=2;j<=n;j++)if(p1[j]/w[j]>p1[max]/w[max])//比较物品的单位价值max=j;p1[max]=0; //标记已经排了序的物品b[i]=max;}(4)排好序,再对物品从排了序的数组中连续装入物品直到装入的重量大于m 时修改最后一个装入的物品的重量和价值:for(i=1,s=0;s<m&&i<=n;i++)s=s+w[b[i]];float w1=w[b[i-1]];if(s!=m) //超出背包容量{ w[b[i-1]]=m-(s-w[b[i-1]]); //装入第b[i-1]个物品的重量p[b[i-1]]=w[b[i-1]]/w1*p[b[i-1]];//装入第b[i-1]个物品的价值}(5)输出最后的结果:for(j=1;j<=i-1;j++)//输出选取的结果{ printf("物品的编号: %d, 可装入该物品的重量: %f \n",b[j],w[b[j]]);pp+=p[b[j]];}printf("总价值%f\n",pp);//装入背包的物品的总价值3.3.3流程图图3-1流程图3.4 测试结果与分析测试结果:*************贪婪算法解决背包问题*************** 请输入物品的个数及背包的总容量物品的总个数: 7背包的总容量: 15物品的编号: 1重量: 2价值:10物品的编号: 2重量: 3价值:5物品的编号: 3重量: 5价值:15物品的编号: 4重量: 7价值:7物品的编号: 5重量: 1价值:6物品的编号: 6重量: 4价值:18物品的编号: 7重量: 1价值:3选择的结果是:物品的编号: 5, 可装入该物品的重量: 1.000000 物品的编号: 1, 可装入该物品的重量: 2.000000 物品的编号: 6, 可装入该物品的重量: 4.000000 物品的编号: 3, 可装入该物品的重量: 5.000000 物品的编号: 7, 可装入该物品的重量: 1.000000 物品的编号: 2, 可装入该物品的重量: 2.000000 总价值55.333332图3-2 问题的解*************贪婪算法解决背包问题***************请输入物品的个数及背包的总容量物品的总个数: 1背包的总容量: 1物品的编号: 1重量: 1价值:3选择的结果是:物品的总重量小于背包的容量故全装入背包,得到的总利润是:3.000000图3-3问题的解从图3-2的解可以看出,物品的重量总和为2+3+5+7+1+4+1=22>15,所以先排序,单位价值从大到小排为:5号,1号,6号,3号,7号,2号,4号;所以应是5号,1号,6号,3号,7号全选,2号选2千克;和结果一样解正确。

相关文档
最新文档