算法设计与分析-第7章-贪心法
算法设计与分析_王红梅_第7章 贪心法
( 3 )解决函数 solution :检查解集合 S 是否构成问 题的完整解。例如,在付款问题中,解决函数是已 付出的货币金额恰好等于应付款。 ( 4 )选择函数 select :即贪心策略,这是贪心法 的关键,它指出哪个候选对象最有希望构成问题的 解,选择函数通常和目标函数有关。例如,在付款 问题中,贪心策略就是在候选集合中选择面值最大 的货币。
C=
∞ 3 3 ∞ 3 7 2 3 6 2
3 7 ∞ 2 5 1
2 3 2 ∞ 3
6 2 5 3 ∞
1
1 2 5 2 2 2
5
4
2
3
(a) 5城市的代价矩阵 2 2
(b) 城市1→城市4 1 2 5
3 4 (c) 城市5→城市2 1 2 3 2 2
5
2 3
5
2
2
5 4
5 3 3 2 (f) 城市2回到出发城市1
例:用贪心法求解付款问题。 假设有面值为5元、2元、1元、5角、2角、1角的货币,需 要找给顾客4元6角现金,为使付出的货币的数量最少,首 先选出1张面值不超过4元6角的最大面值的货币,即2元, 再选出1张面值不超过2元6角的最大面值的货币,即2元, 再选出1张面值不超过6角的最大面值的货币,即5角,再选 出1张面值不超过1角的最大面值的货币,即1角,总共付出 4张货币。
7.2.2 图着色问题
给定无向连通图 G=(V, E) ,求图 G的最小色数 k , 使得用k种颜色对G中的顶点着色,可使任意两个相 邻顶点着色不同。
例如,图7.3(a)所示的图可以只用两种颜色着色,将 顶点1、3和4着成一种颜色,将顶点2和顶点5着成另 外一种颜色。为简单起见,下面假定k个颜色的集合 为{颜色1, 颜色2, …, 颜色k}。 3
贪心算法程序设计
贪心算法程序设计贪心算法程序设计1. 什么是贪心算法贪心算法(Greedy Algorithm)是一种常见的算法思想,它在每一步选择中都采取当前状态下的最优选择,从而希望最终达到全局最优解。
贪心算法的核心思想是局部最优解能导致全局最优解。
2. 贪心算法的基本步骤贪心算法的基本步骤如下:1. 定义问题的优化目标。
2. 将问题分解成子问题。
3. 选择当前最优的子问题解,将子问题的解合并成原问题的解。
4. 检查是否达到了问题的优化目标,如果没有达到,则回到第二步,继续寻找下一个最优子问题解。
5. 在所有子问题解合并成原问题解后,得到问题的最优解。
3. 贪心算法的应用场景贪心算法的应用非常广泛,几乎可以用于解决各种优化问题。
以下几个常见的应用场景:1. 零钱找零问题:给定一定面额的纸币和硬币,如何找零使得所需纸币和硬币的数量最小?2. 区间调度问题:给定一些活动的开始时间和结束时间,如何安排活动使得可以办理的活动数量最大?3. 背包问题:给定一些具有重量和价值的物品,如何选择物品使得背包的总价值最大?4. 最小树问题:给定一个带权无向图,如何找到一棵树,使得它的边权之和最小?5. 哈夫曼编码问题:给定一组字符和相应的频率,如何构造一个满足最低编码长度限制的二进制编码?4. 贪心算法的优缺点贪心算法的优点是简单、高效,可以快速得到一个近似最优解。
而且对于一些问题,贪心算法能够得到全局最优解。
贪心算法的缺点在于它不一定能够得到全局最优解,因为在每一步只考虑局部最优解,无法回溯到之前的选择。
5. 贪心算法的程序设计在使用贪心算法进行程序设计时,通常需要以下几个步骤:1. 定义问题的优化目标。
2. 将问题分解成子问题,并设计子问题的解决方案。
3. 设计贪心选择策略,选择局部最优解。
4. 设计贪心算法的递推或迭代公式。
5. 判断贪心算法是否能够得到全局最优解。
6. 编写程序实现贪心算法。
6.贪心算法是一种常见的算法思想,它在每一步选择中都采取当前状态下的最优选择,从而希望最终达到全局最优解。
贪心算法知识点总结
贪心算法知识点总结1. 基本原理贪心算法的基本原理是每一步都选择当前状态下的最优解,以期望最终得到全局最优解。
具体来说,贪心算法通常可以分为以下几个步骤:1)从问题的某个初始解出发2)采用一种迭代的方式,逐步将初始解进行优化3)每一步都是基于当前状态的最优选择来进行优化4)直到无法再进行优化,得到问题的最优解由于贪心算法每一步都要选择局部最优解,因此贪心算法通常具有高效性。
然而,贪心算法并不适用于所有问题,其结果不一定是全局最优解。
因此,在使用贪心算法时需要注意问题的特性和约束条件,以免得到错误的结果。
2. 适用情况贪心算法通常适用于满足以下条件的问题:1)问题的最优解满足“最优子结构”性质:即问题的最优解包含了其子问题的最优解2)问题的求解过程具有“贪心选择性”:即每一步都选择当前状态下的最优解,并不需要考虑未来的后果3)问题的约束条件可以通过局部最优选择满足全局最优解:即问题的解空间中存在一些局部最优解,可以通过一系列的局部最优解构建全局最优解在实际应用中,贪心算法通常用于求解最优化问题,如最小生成树、最短路径、任务调度等问题。
由于贪心算法的高效性,它通常能够在较短的时间内得到较为接近最优解的结果。
然而,贪心算法并不适用于所有问题,对于一些问题,贪心算法将得到错误的结果。
因此,在使用贪心算法时需要谨慎选择问题类型和约束条件,以避免错误的结果。
3. 贪心算法实例在下面的部分,我们将介绍一些常见的贪心算法实例,包括背包问题、活动安排问题、霍夫曼编码等。
3.1 背包问题背包问题是一个经典的优化问题,它包括0-1背包问题、分数背包问题等多种类型。
在0-1背包问题中,给定n种物品和一个容量为C的背包,每种物品i的重量为w[i],价值为v[i],求在不超过背包容量的情况下,如何选择物品放入背包,可以使得背包中的总价值最大。
对于0-1背包问题,贪心算法通常不能得到最优解。
然而,在分数背包问题中,贪心算法通常可以得到近似的最优解。
《算法分析与设计》(李春葆版)课后选择题答案与解析
《算法及其分析》课后选择题答案及详解第1 章——概论1.下列关于算法的说法中正确的有()。
Ⅰ.求解某一类问题的算法是唯一的Ⅱ.算法必须在有限步操作之后停止Ⅲ.算法的每一步操作必须是明确的,不能有歧义或含义模糊Ⅳ.算法执行后一定产生确定的结果A.1个B.2个C.3个D.4个2.T(n)表示当输入规模为n时的算法效率,以下算法效率最优的是()。
A.T(n)=T(n-1)+1,T(1)=1B.T(n)=2nC.T(n)= T(n/2)+1,T(1)=1D.T(n)=3nlog2n答案解析:1.答:由于算法具有有穷性、确定性和输出性,因而Ⅱ、Ⅲ、Ⅳ正确,而解决某一类问题的算法不一定是唯一的。
答案为C。
2.答:选项A的时间复杂度为O(n)。
选项B的时间复杂度为O(n)。
选项C 的时间复杂度为O(log2n)。
选项D的时间复杂度为O(nlog2n)。
答案为C。
第3 章─分治法1.分治法的设计思想是将一个难以直接解决的大问题分割成规模较小的子问题,分别解决子问题,最后将子问题的解组合起来形成原问题的解。
这要求原问题和子问题()。
A.问题规模相同,问题性质相同B.问题规模相同,问题性质不同C.问题规模不同,问题性质相同D.问题规模不同,问题性质不同2.在寻找n个元素中第k小元素问题中,如快速排序算法思想,运用分治算法对n个元素进行划分,如何选择划分基准?下面()答案解释最合理。
A.随机选择一个元素作为划分基准B.取子序列的第一个元素作为划分基准C.用中位数的中位数方法寻找划分基准D.以上皆可行。
但不同方法,算法复杂度上界可能不同3.对于下列二分查找算法,以下正确的是()。
A.intbinarySearch(inta[],intn,int x){intlow=0,high=n-1;while(low<=high){intmid=(low+high)/2;if(x==a[mid])returnmid;if(x>a[mid])low=mid;elsehigh=mid;}return –1;}B.intbinarySearch(inta[],intn,int x) { intlow=0,high=n-1;while(low+1!=high){intmid=(low+high)/2;if(x>=a[mid])low=mid;elsehigh=mid;}if(x==a[low])returnlow;elsereturn –1;}C.intbinarySearch(inta[],intn,intx) { intlow=0,high=n-1;while(low<high-1){intmid=(low+high)/2;if(x<a[mid])high=mid;elselow=mid;}if(x==a[low])returnlow;elsereturn –1;}D.intbinarySearch(inta[],intn,int x) {if(n>0&&x>=a[0]){intlow= 0,high=n-1;while(low<high){intmid=(low+high+1)/2;if(x<a[mid])high=mid-1;elselow=mid;}if(x==a[low])returnlow;}return –1;}答案解析:1.答:C。
贪心法
贪心法贪心法(Greedy Approach)又称贪婪法, 在对问题求解时,总是做出在当前看来是最好的选择,或者说是:总是作出在当前看来最好的选择。
也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。
当然,希望贪心算法得到的最终结果也是整体最优的。
虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。
如单源最短路经问题,最小生成树问题等。
在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。
贪心法的设计思想当一个问题具有以下的性质时可以用贪心算法求解:每一步的局部最优解,同事也说整个问题的最优解。
如果一个问题可以用贪心算法解决,那么贪心通常是解决这个问题的最好的方法。
贪婪算法一般比其他方法例如动态规划更有效。
但是贪婪算法不能总是被应用。
例如,部分背包问题可以使用贪心解决,但是不能解决0-1背包问题。
贪婪算法有时也用用来得到一个近似优化问题。
例如,旅行商问题是一个NP难问题。
贪婪选择这个问题是选择最近的并且从当前城市每一步。
这个解决方案并不总是产生最好的最优解,但可以用来得到一个近似最优解。
让我们考虑一下任务选择的贪婪算法的问题, 作为我们的第一个例子。
问题:给出n个任务和每个任务的开始和结束时间。
找出可以完成的任务的最大数量,在同一时刻只能做一个任务。
例子:下面的6个任务:start[] = {1, 3, 0, 5, 8, 5};finish[] = {2, 4, 6, 7, 9, 9};最多可完成的任务是:{0, 1, 3, 4}贪婪的选择是总是选择下一个任务的完成时间至少在剩下的任务和开始时间大于或等于以前选择任务的完成时间。
我们可以根据他们的任务完成时间,以便我们总是认为下一个任务是最小完成时间的任务。
1)按照完成时间对任务排序2)选择第一个任务排序数组元素和打印。
3) 继续以下剩余的任务排序数组。
……a)如果这一任务的开始时间大于先前选择任务的完成时间然后选择这个任务和打印。
算法设计与分析讲义贪心法
贪心算法在每一步选择时都采取在当前状态下最好或最优( 即最有利)的选择,而不考虑可能出现的后果。
贪心算法与动态规划
贪心算法是一种局部最优策略,即每一步选择在当前状态下 是最优的,但不一定能够得到全局最优解。
动态规划是一种全局最优策略,通过将问题分解为子问题, 逐步求解得到全局最优解。
贪心算法的历史与发展
选择适当的贪心策略
选择适当的贪心策略可以最大程度 地减少计算时间。
空间优化
通过优化算法的空间复杂度,减少 算法的空间占用,以提高算法的效 率。
并行计算
利用并行计算技术,将算法并行化 ,以提高算法的运行速度。
数据结构优化
使用合适的数据结构可以加快算法 的执行速度,如哈希表、堆等。
06
贪心算法的应用扩展
贪心算法的优化策略
总结词
记忆化搜索、动态规划优化、全局状态决策
详细描述
贪心算法虽然能够得到问题的近似解,但在某些情况 下可能无法得到最优解。为了提高贪心算法的性能, 可以采用一些优化策略,例如记忆化搜索,将已经计 算过的状态存储下来,避免重复计算;动态规划优化 ,将问题分解为子问题,通过解决子问题来解决原问 题;全局状态决策,将问题的所有状态作为一个整体 来考虑,利用问题的整体性质来得到更好的解。
在资源分配问题中,贪心算法可以用于求解具有单位资源的最大权值
组合问题、分数背包问题等。
05
贪心算法的实现技巧
贪心算法的编程实现
确定贪心策略
根据问题特性确定贪心策略,通常选择最优解或近似最优解。
编码实现
将贪心策略转化为代码实现,通常使用循环和条件语句实现算 法。
测试样例
设计测试样例,覆盖各种情况,提高算法的健壮性和正确性。
《算法设计与分析》第07章
南京邮电大学计算机学院 2008年3月
for (int r=2; r<=n;r++) for (int i=0;i<=n-r;i++) { int j=i+r-1; m[i][j]=m[i+1][j]+p[i]*p[i+1]*p[j+1]; s[i][j]=i; for (int k=i+1;k<j;k++) { int t=m[i][k] +m[k+1][j]+p[i]*p[k+1]*p[j+1]; if (t<m[i][j]) { m[i][j]=t;s[i][j]=k; } } } return m[0][n-1];
南京邮电大学计算机学院 2008年3月
for (int j=n-2;j>=0;j--){ float min=INFTY; for (ENode<T> *r=a[j];r;r=r->nextArc) { int v=r->adjVex; if (r->w+cost[v]<min) { min=r->w+cost[v];q=v; } } cost[j]=min;d[j]=q; } p[0]=0;p[k-1]=n-1; for(j=1;j<=k-2;j++) p[j]=d[p[j-1]]; delete []cost;delete []d; }
南京邮电大学计算机学院 2008年3月
7.3.3 矩阵连乘算法
【程序7-3】矩阵连乘算法 class MatrixChain { public: MatrixChain(int mSize,int *q); int MChain(); int LookupChain(); void Traceback(); ……
贪心算法PPT课件
安排方案
f1
B
安排方案
fk
B’
…… 共j个活动
可能 相同 不存在
……
可能
如果 B’包 含这 个活, 则B 一定 包含
9
(2) 时间复杂度分析: 因为排序过程可以在O(nlogn)时间内完成,而求最优活动子 集的过程只需O(n)次比较,因此这个算法的时间复杂度为 O(nlogn)。 (3) 贪心策略设计算法的一般特点
·选Si最小的,这样可以增大场地的利用率; ·选fi最小的,使得下一个活动可以更早开始。
由于活动的占用时间长度没有限制,因此后一选择更合理。
6
为了在每一次选择时取当前可以安排的活动中最早结束的活动,应首先把 n项活动按结束时间的先后进行升序排序。即,使f1≤f2≤…≤fn,然后在Si值 不小于当前时刻的活动中取fi值最小者。 算法:
·算法的设计比较简单; ·算法一般比较快速; ·算法的正确性一般不明显,需要论证;如果正确性不能保 证,那么它往往可以得到近似最优解。
10
5.2 背包(Knapsack)问题
1. 问题描述
已知:n个(应为n种)物体{1,2,…,n}与一个背包。物体i的重量 (或体积)为Wi>0,价值为Pi>0(i=1,2,…,n),背包容量为 M>0。
计算机算法 ——设计与分析导论
刘璟
1
Chapter 5. 贪心(Greedy)技术
❖ 5.1 贪心策略的思想 ❖ 5.2 背包(Knapsack)问题 ❖ 5.3 Huffman编码 ❖ 5.4 多机调度问题的近似解法 ❖ 5.5 单源最短路径的Dijkstra算法
算法设计与分析动态规划与贪心算法的应用
算法设计与分析动态规划与贪心算法的应用算法设计与分析:动态规划与贪心算法的应用一、引言算法设计与分析是计算机科学中的重要课题之一。
动态规划与贪心算法是常用的解决问题的方法。
本文将分析和探讨动态规划与贪心算法的应用,为读者提供深入了解算法设计与分析的知识。
二、动态规划的应用动态规划是一种将问题拆分为子问题并逐步求解的算法。
它通常用于解决具有重叠子问题性质的问题,通过保存每个子问题的解,避免了重复计算,提高了计算效率。
1. 背包问题背包问题是动态规划中的经典问题之一。
给定一个背包容量和一系列物品的重量和价值,求在背包容量限制下,如何选择物品使得总价值最大。
通过动态规划的思想,我们可以逐步求解子问题,并得到最优解。
2. 最长公共子序列最长公共子序列是算法设计中的另一个经典问题。
对于两个序列,找出它们最长的共同子序列长度。
通过定义状态转移方程,我们可以利用动态规划的方法解决这一问题,提高计算效率。
三、贪心算法的应用贪心算法是一种简单而有效的算法,它通过每一步选择当前最优解来求解整个问题。
贪心算法通常适用于满足最优子结构性质并能通过贪心选择获得全局最优解的问题。
1. 零钱兑换问题零钱兑换问题是贪心算法的一个经典应用。
给定一些面额不同的硬币和一个需要凑齐的金额,求凑齐该金额所需的最少硬币数。
贪心算法可以通过每次选择面额最大的硬币来逐步逼近最优解。
2. 活动选择问题活动选择问题是贪心算法的另一个常见应用。
给定一些活动的开始时间和结束时间,求能参加的最多活动数。
通过贪心选择结束时间最早的活动,我们可以逐步求解最优解。
四、动态规划与贪心算法的比较动态规划与贪心算法都是解决问题的有效方法,但它们在某些方面存在差异。
1. 最优子结构动态规划适用于具有最优子结构性质的问题,而贪心算法则适用于满足贪心选择性质的问题。
最优子结构指子问题的最优解能够构成原问题的最优解,贪心选择性质指每一步都选择当前最优解。
2. 时间复杂度动态规划通常需要保存中间结果,可能会导致较高的空间复杂度。
贪心法
贪心算法一、基本概念:所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择。
也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。
贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择。
必须注意的是,贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关。
所以对所采用的贪心策略一定要仔细分析其是否满足无后效性。
二、贪心算法的基本思路:1.建立数学模型来描述问题。
2.把求解的问题分成若干个子问题。
3.对每一子问题求解,得到子问题的局部最优解。
4.把子问题的解局部最优解合成原来解问题的一个解。
三、贪心算法适用的问题贪心策略适用的前提是:局部最优策略能导致产生全局最优解。
实际上,贪心算法适用的情况很少。
一般,对一个问题分析是否适用于贪心算法,可以先选择该问题下的几个实际数据进行分析,就可做出判断。
四、贪心算法的实现框架从问题的某一初始解出发;while (能朝给定总目标前进一步){利用可行的决策,求出可行解的一个解元素;}由所有解元素组合成问题的一个可行解;五、贪心策略的选择因为用贪心算法只能通过解局部最优解的策略来达到全局最优解,因此,一定要注意判断问题是否适合采用贪心算法策略,找到的解是否一定是问题的最优解。
六、例题分析下面是一个可以试用贪心算法解的题目,贪心解的确不错,可惜不是最优解。
[背包问题]有一个背包,背包容量是M=150。
有7个物品,物品可以分割成任意大小。
要求尽可能让装入背包中的物品总价值最大,但不能超过总容量。
物品A B C D E F G重量35 30 60 50 40 10 25价值10 40 30 50 35 40 30分析:目标函数:∑pi最大约束条件是装入的物品总重量不超过背包容量:∑wi<=M( M=150)(1)根据贪心的策略,每次挑选价值最大的物品装入背包,得到的结果是否最优?(2)每次挑选所占重量最小的物品装入是否能得到最优解?(3)每次选取单位重量价值最大的物品,成为解本题的策略。
算法设计与分析 王红梅 第二版 第7章_贪心算法
2015/11/4
Chapter 7 Greedy Method
3
第7章 贪心算法
贪心法把一个复杂问题的解分解为一系列较为简单 的局部最优选择,每一步选择都是对当前解的一个 扩展,直到获得问题的完整解。 贪心法的典型应用是求解最优化问题,而且对许多 问题都能得到整体最优解,即使不能得到整体最优 解,通常也是最优解的很好近似。
2015/11/4
Chapter 7 Greedy Method
22
7.2.1 TSP问题
设图G 有 n 个顶点, w[n][n] 存储边上的代价,集合 E‘存储是候选集合中未选取的边,集合 P 存储经过的边,最 短链接策略求解 TSP 问题的算法如下:
算法7.3——最短链接策略求解TSP问题 1.P={ }; 2.E'=E; //候选集合,初始时为图中所有边 3.循环直到集合P中包含n-1条边 3.1 在E'中选取最短边(u, v); 3.2 E'=E'-{(u, v)}; 3.3 如果 (顶点 u 和v 在 P 中不连通 and 不产生分枝) 则P=P+{(u, v)};
由于
A/B-1/E=((A*E)-B)/(B*E)
这个分数可能存在公因子,所以需要化简,可将分子和分母同 时除以最大公约数。
2015/11/4 Chapter 7 Greedy Method 11
7.1.2 一个简单的例子——埃及分数
[算法]伪代码描述如下: 算法7.1:埃及分数EgyptFraction 输入:真分数的分子A和分母B 输出:最少的埃及分数之和 1. E=B/A+1; //E=C+1 2. 输出1/E; 3. A=A*E-B; B=B*E; 4. 求A和B的最大公约数R,如果R不为1,将A和B同时除以R 5. 如果A等于1,则输出1/B,算法结束;否则转步骤1
算法设计与分析讲义贪心法
贪心算法的历史与发展
01
贪心算法源于1944年数学家John von Neumann在博弈论中的“Oligopoly” 算法,用于解决多人零和博弈问题;
02
1954年,Garey和Johnson提出了贪心算法的基础概念和方法,并成功应用于 解决一些组合优化问题;
03
随着计算机科学和人工智能的快速发展,贪心算法在许多领域得到了广泛应用 和发展,例如最短路径问题、最小生成树问题、作业调度问题等。
找零问题
总结词
最优找零策略,时间复杂度为O(logn)
详细描述
在找零时,贪心算法可以帮助我们制定最优找零策略,通过计算货币单位的最小公倍数,将找零的货 币单位从小到大排序,然后依次考虑每个货币单位,直到找零的总额达到商品价格为止。
背包问题
总结词
最优解,时间复杂度为O(nW),其中n为物品数量,W为背包容量
06
总结与展望
贪心算法的优缺点
• 优点 • 简单易懂:贪心算法的思路通常比较直观,易于理解,适合初学者快速上手。 • 高效:在某些情况下,贪心算法的执行效率可以非常高,例如对于一些最优子结构的问题,时间复杂度可
以达到 O(n)。 • 适用范围广:贪心算法可以应用于许多不同类型的问题,具有较广的适用性。 • 缺点 • 正确性难以保证:对于某些问题,贪心算法可能无法得到正确的结果,因为它们不能保证全局最优。 • 不一定收敛:贪心算法在某些情况下可能不收敛,不能得到最终的解。 • 需要良好的初始化:贪心算法通常需要一个良好的初始化,否则可能会陷入局部最优解。
贪心算法未来的发展方向
• 理论研究 • 研究贪心算法的理论基础,探讨其适用范围和限制,以更好地理解其性质和行为。 • 深入研究贪心算法在不同类型问题中的应用,拓展其应用范围。 • 研究贪心算法与其他算法之间的关系和比较,以更全面地了解各种算法的优势和劣势。 • 应用研究 • 在实际应用中,研究如何更好地利用贪心算法来解决各种问题,提高其解决问题的效率和性能。 • 研究如何将贪心算法与其他算法相结合,以充分发挥各自的优势,提高解决问题的效率和正确性。 • 计算复杂性研究 • 研究贪心算法的时间复杂度和空间复杂度,以更好地了解其计算效率和资源占用情况。 • 研究如何优化贪心算法的实现,提高其计算效率和可扩展性。
算法分析与设计实验二贪心算法
算法分析与设计实验二贪心算法贪心算法(Greedy Algorithm)是一种常用的算法设计方法,其核心思想是在每一步都做出当前情况下最优选择,以期望最终得到全局最优解。
本实验主要介绍贪心算法的原理、应用和分析。
一、贪心算法的原理贪心算法的基本思路是在每一步都做出当前情况下最优选择,并且不考虑当前选择对后续选择的影响。
贪心算法通常采用贪心选择策略和最优子结构两个基本要素。
1.贪心选择策略贪心选择策略是指在每一步都选择当前情况下最优解的策略。
这种策略要求我们能够证明,通过选择当前最优解,可以使得问题的规模减小到原问题的一个子问题,并且该子问题的最优解一定包含在全局最优解中。
2.最优子结构最优子结构是指问题的最优解包含其子问题的最优解。
贪心算法求解问题的过程通常包括两个步骤,选择最优子结构和利用最优子结构得到最优解。
二、贪心算法的应用1.集合覆盖问题集合覆盖问题是指在给定的一组集合中,找出最小的子集合,使得这些子集合的并集包含所有的元素。
贪心算法可以通过每一步选择包含最多未覆盖元素的集合,直到覆盖所有元素为止。
2.挑选活动问题挑选活动问题是指在给定一组活动的起始时间和结束时间,找出最大的相容活动子集合。
贪心算法可以通过每一步选择结束时间最早的活动,之后将该活动与其他相容的活动进行比较,从而得到最大的相容活动子集合。
3.分数背包问题分数背包问题是指在给定一组物品和一个背包容量的情况下,选择部分物品放入背包,使得放入背包的物品总价值最大。
贪心算法可以通过每一步选择单位重量价值最高的物品,直到背包容量不足为止。
三、贪心算法的分析贪心算法通常具有高效性和近似最优性的特点。
由于贪心算法每一步都选择当前最优解,不进行回溯和剪枝的操作,因此贪心算法的时间复杂度较低。
然而,贪心算法并不总能得到问题的最优解,它通常只能得到近似最优解。
贪心算法的近似性证明可以分为两步。
首先,我们需要证明贪心选择策略的正确性,即每一步选择的最优解一定包含在全局最优解中。
第7章 贪心法-算法设计与分析(第2版)-李春葆-清华大学出版社
{ SolutionType x={};
//初始时,解向量不包含任何分量
for (int i=0;i<n;i++)
//执行n步操作
{ SType xi=Select(a);
//从输入a中选择一个当前最好的分量
if (Feasiable(xi))
//判断xi是否包含在当前解中
solution=Union(x,xi); //将xi分量合并形成x
} } }
//求解最大兼容活动子集 //初始化为false //A[1..n]按活动结束时间递增排序 //前一个兼容活动的结束时间 //扫描所有活动 //找到一个兼容活动 //选择A[i]活动 //更新preend值
【算法分析】算法的主要时间花费在排序上,排序时间为
O(nlog2n),所以整个算法的时间复杂度为O(nlog2n)。
问题的最优子结构性质是该问题可用动态规划算法或贪心法求解 的关键特征。
7.1.3 贪心法的一般求解过程
贪心法求解问题的算法框架如下:
SolutionType Greedy(SType a[],int n)
//假设解向量(x0,x1,…,xn-1)类型为SolutionType,其分量为SType类型
//标记选择的活动 //选取的兼容活动个数
void solve() { memset(flag,0,sizeof(flag));
sort(A+1,A+n+1); int preend=0; for (int i=1;i<=n;i++) { if (A[i].b>=preend)
{ flag[i]=true; preend=A[i].e;
算法设计与分析论文(贪心算法)
贪心选择是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪 心选择来达到。这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划 算法的主要区别。
贪心选择是采用从顶向下、以迭代的方法做出相继选择,每做一次贪心选择 就将所求问题简化为一个规模更小的子问题。对于一个具体问题,要确定它是否 具有贪心选择的性质,我们必须证明每一步所作的贪心选择最终能得到问题的最 优解。通常可以首先证明问题的一个整体最优解,是从贪心选择开始的,而且作 了贪心选择后,原问题简化为一个规模更小的类似子问题。然后,用数学归纳法 证明,通过每一步贪心选择,最终可得到问题的一个整体最优解。
物品超出背包容量为止。伪代码如下:
public static void DepWePr(double[][] a, double c, int[] ans) { // depend on
// the // weight // and price double[] w = new double[a[0].length]; // the weight of goods System.arraycopy(a[0], 0, w, 0, w.length); // copy the array
贪心算法
——不在贪心中爆发,就在贪心中灭亡 徐晓龙 武汉理工大学计算机科学与技术学院软件 ZY1101 班
摘要
本文介绍贪心算法的基本意义以及算法的使用范围,并通过具体的案例来分 析贪心算法的具体应用,从而指出其特点和存在问题。 关键字:贪心算法,贪心策略,TSP、0/1 背包
引言
我们用了 13 周的时间学完了《算法设计与分析》这本书。这本书中涵盖了 大量的常见算法,包括蛮力法、分治法、动态规划法、贪心算法等等。我最有印 象的就是贪心算法。贪心算法是一种有合理的数据组织和清晰高效的算法,它简 单有效。下面我们来详细解读一下这个算法。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
清华大学出版社
算法设计与分析
(3)解决函数solution:检查解集合S是否构成问 题的完整解。例如,在付款问题中,解决函数是已 付出的货币金额恰好等于应付款。
(4)选择函数select:即贪心策略,这是贪心法 的关键,它指出哪个候选对象最有希望构成问题的 解,选择函数通常和目标函数有关。例如,在付款 问题中,贪心策略就是在候选集合中选择面值最大 的货币。
2
5
5
4 23
4 23
4 23
(d) 城市4→城市3 (e) 城市3→城市5 (f) 城市2回到出发城市1
最短链接贪心策略求解TSP问题的过程
清华大学出版社
算法设计与分析
设图G有n个顶点,边上的代价存储在二维数组w[n][n]中, 集合E'是候选集合即存储所有未选取的边,集合P存储经过的 边,最短链接策略求解TSP问题的算法如下:
清华大学出版社
算法设计与分析
第7章 贪心法
7.1 概 述 7.2 图问题中的贪心法 7.3 组合问题中的贪心法 7.4 实验项目——哈夫曼编码
清华大学出版社
7.1 概 述
算法设计与分析
7.1.1 贪心法的设计思想 7.1.2 贪心法的求解过程
清华大学出版社
算法设计与分析
7.1.1 贪心法的设计思想
3.2 P=P+{(u, v)}; 3.3 V=V-{v}; 3.4 u=v; //从顶点v出发继续求解
清华大学出版社
算法设计与分析
算法7.1的时间性能为O(n2),因为共进行n-1次贪心选择, 每一次选择都需要查找满足贪心条件的最短边。
用最近邻点贪心策略求解TSP问题所得的结果不一定是 最优解,图7.1(a)中从城市1出发的最优解是 1→2→5→4→3→1,总代价只有13。当图中顶点个数较多 并且各边的代价值分布比较均匀时,最近邻点策略可以给 出较好的近似解,不过,这个近似解以何种程度近似于最 优解,却难以保证。例如,在图7.1中,如果增大边(2, 1)的 代价,则总代价只好随之增加,没有选择的余地。
7.2.3 最小生成树问题
设G=(V,E)是一个无向连通网,生成树上 各边的权值之和称为该生成树的代价,在G的所 有生成树中,代价最小的生成树称为最小生成树 (Minimal Spanning Trees)。
清华大学出版社
算法设计与分析
最小生成树问题至少有两种合理的贪心策略:
(1)最近顶点策略:任选一个顶点,并以此建立 起生成树,每一步的贪心选择是简单地把不在生 成树中的最近顶点添加到生成树中。
Prim算法就应用了这个贪心策略,它使生成树 以一种自然的方式生长,即从任意顶点开始,每 一步为这棵树添加一个分枝,直到生成树中包含 全部顶点。
清华大学出版社
算法设计与分析
34 B
12
34 B
12
A 19
26 E
F
46 25
25 38
A 19
26 E
F
46 25
25 38
C
D
17
(a) 连通网,U={A} cost={(A, B)34,(A, C)46,
3
1
2
5
4
清华大学出版社
算法设计与分析
贪心策略:选择一种颜色,以任意顶点作为开始顶点,依次 考察图中的未被着色的每个顶点,如果一个顶点可以用颜色1 着色,换言之,该顶点的邻接点都还未被着色,则用颜色1为 该顶点着色,当没有顶点能以这种颜色着色时,选择颜色2和 一个未被着色的顶点作为开始顶点,用第二种颜色为尽可能 多的顶点着色,如果还有未着色的顶点,则选取颜色3并为尽 可能多的顶点着色,依此类推。
(A, D)∞,(A, E)∞,(A, F)19}
C
D
17
(b) U={A, F} cost={(A, B)34,(F, C)25, (F, D)25,(F, E)26}
34 B
12
A 19
26 E
F
46 25
25 38
C
D
17
(c) U={A, F ,C} cost={(A, B)34, (C, D)17,(F, E)26}
设图G有n个顶点,边上的代价存储在二维数组w[n][n] 中,集合V存储图的顶点,集合P存储经过的边,最近邻点 策略求解TSP问题的算法如下:
算法7.1——最近邻点策略求解TSP问题//从顶点u0出发 3. 循环直到集合P中包含n-1条边
3.1 查找与顶点u邻接的最小代价边(u, v)并且v属于集合V;
清华大学出版社
算法设计与分析
在付款问题每一步的贪心选择中,在不超过 应付款金额的条件下,只选择面值最大的货币, 而不去考虑在后面看来这种选择是否合理,而且 它还不会改变决定:一旦选出了一张货币,就永 远选定。付款问题的贪心选择策略是尽可能使付 出的货币最快地满足支付要求,其目的是使付出 的货币张数最慢地增加,这正体现了贪心法的设 计思想。
清华大学出版社
算法设计与分析
贪心法求解的问题的特征:
(1)最优子结构性质
当一个问题的最优解包含其子问题的最优解时,
称此问题具有最优子结构性质,也称此问题满足最 优性原理。
(2)贪心选择性质
所谓贪心选择性质是指问题的整体最优解可以 通过一系列局部最优的选择,即贪心选择来得到。
动态规划法通常以自底向上的方式求解各个子问 题,而贪心法则通常以自顶向下的方式做出一系列 的贪心选择。
清华大学出版社
算法设计与分析
7.1.2 贪心法的求解过程
用贪心法求解问题应该考虑如下几个方面:
(1)候选集合C:为了构造问题的解决方案,有一 个候选集合C作为问题的可能解,即问题的最终解 均取自于候选集合C。例如,在付款问题中,各种 面值的货币构成候选集合。
(2)解集合S:随着贪心选择的进行,解集合S不 断扩展,直到构成一个满足问题的完整解。例如, 在付款问题中,已付出的货币构成解集合。
(f) U={A, F, C, D, E, B}
cost={(E, B)12}
cost={ }
Prim算法构造最小生成树的过程示意
清华大学出版社
算法设计与分析
设图G中顶点的编号为0~n-1,Prim算法如下:
算法7.4——Prim算法
1. 初始化两个辅助数组lowcost和adjvex; 2. U={u0}; 输出顶点u0; //将顶点u0加入生成树中 3. 重复执行下列操作n-1次
4.1 k++; //取下一个颜色 4.2 for (i=2; i<=n; i++) //用颜色k为尽量多的顶点着色
4.2.1 若顶点i已着色,则转步骤4.2,考虑下一个顶点; 4.2.2 若图中与顶点i邻接的顶点着色与顶点i着颜色k不冲突,
则color[i]=k; 5.输出k;
清华大学出版社
算法设计与分析
清华大学出版社
算法设计与分析
在算法7.2中,如果操作“在E'中选取最短边 (u, v)”用顺序查找,则算法7.2的时间性能是 O(n2),如果采用堆排序的方法将集合E'中的边 建立堆,则选取最短边的操作可以是O(log2n), 对于两个顶点是否连通以及是否会产生分枝,可
以用并查集的操作将其时间性能提高到O(n),此 时算法7.2的时间性能为O(nlog2n)。
34 B
12
A 19
26 E
F
46 25
25 38
34 B
12
A 19
26 E
F
46 25
25 38
34 B
12
A 19
26 E
F
46 25
25 38
C
D
17
C
D
17
C
D
17
(d) U={A, F, C, D} cost={(A, B)34, (F, E)26}
(e) U={A, F, C, D, E}
清华大学出版社
算法设计与分析
例:用贪心法求解付款问题。 假设有面值为5元、2元、1元、5角、2角、1角的货币,需 要找给顾客4元6角现金,为使付出的货币的数量最少,首 先选出1张面值不超过4元6角的最大面值的货币,即2元, 再选出1张面值不超过2元6角的最大面值的货币,即2元, 再选出1张面值不超过6角的最大面值的货币,即5角,再选 出1张面值不超过1角的最大面值的货币,即1角,总共付出 4张货币。
(5)可行函数feasible:检查解集合中加入一个候 选对象是否可行,即解集合扩展后是否满足约束条 件。例如,在付款问题中,可行函数是每一步选择 的货币和已付出的货币相加不超过应付款。
清华大学出版社
贪心法的一般过程
算法设计与分析
Greedy(C) //C是问题的输入集合即候选集合
{ S={ }; //初始解集合为空集 while (not solution(S)) //集合S没有构成问题的一个解
3.1 在lowcost中选取最短边,取adjvex中对应的顶点序号k; 3.2 输出顶点k和对应的权值; 3.3 U=U+{k}; 3.4 调整数组lowcost和adjvex;
设连通网中有n个顶点,则第一个进行初始化的循环语句需 要执行n-1次,第二个循环共执行n-1次,内嵌两个循环, 其一是在长度为n的数组中求最小值,需要执行n-1次,其 二是调整辅助数组,需要执行n-1次,所以,Prim算法的时 间复杂度为O(n2)。
3
1
2
5
3
14
2
5
4
清华大学出版社
算法设计与分析
设数组color[n]表示顶点的着色情况,贪心法求解图 着色问题的算法如下:
算法7.3——图着色问题
1.color[1]=1; //顶点1着颜色1 2.for (i=2; i<=n; i++) //其他所有顶点置未着色状态