实验二 贪心算法

合集下载

贪心算法-找零问题 实验报告

贪心算法-找零问题 实验报告

实验三课程名称:算法设计与实现实验名称:贪心算法-找零问题实验日期:2019年5月2日仪器编号:007班级:数媒0000班姓名:郝仁学号0000000000实验内容假设零钱系统的币值是{1,p,p^2,……,p^n},p>1,且每个钱币的重量都等于1,设计一个最坏情况下时间复杂度最低的算法,使得对任何钱数y,该算法得到的零钱个数最少,说明算法的主要设计思想,证明它的正确性,并给出最坏情况下的时间复杂度。

实验分析引理1(离散数学其及应用3.1.4):若n是正整数,则用25美分、10美分、5美分和1美分等尽可能少的硬币找出的n美分零钱中,至多有2个10美分、至多有1个5美分、至多有4个1美分硬币,而不能有2个10美分和1个5美分硬币。

用10美分、5美分和1美分硬币找出的零钱不能超过24美分。

证明如果有超过规定数目的各种类型的硬币,就可以用等值的数目更少的硬币来替换。

注意,如果有3个10美分硬币,就可以换成1个25美分和1个5美分硬币;如果有2个5美分硬币,就可以换成1个10美分硬币;如果有5个1美分硬币,就可以换成1个5美分硬币;如果有2个10美分和1个5美分硬币,就可以换成1个25美分硬币。

由于至多可以有2个10美分、1个5美分和4个1美分硬币,而不能有2个10美分和1个5美分硬币,所以当用尽可能少的硬币找n美分零钱时,24美分就是用10美分、5美分和1美分硬币能找出的最大值。

假设存在正整数n,使得有办法将25美分、10美分、5美分和1美分硬币用少于贪心算法所求出的硬币去找n美分零钱。

首先注意,在这种找n美分零钱的最优方式中使用25美分硬币的个数q′,一定等于贪心算法所用25美分硬币的个数。

为说明这一点,注意贪心算法使用尽可能多的25美分硬币,所以q′≤q。

但是q′也不能小于q。

假如q′小于q,需要在这种最优方式中用10美分、5美分和1美分硬币至少找出25美分零钱。

而根据引理1,这是不可能的。

贪心算法基本步骤

贪心算法基本步骤

贪心算法基本步骤贪心算法是一种非常常用的算法思想,广泛应用于算法设计中。

本文将介绍贪心算法的基本步骤、实现方式、应用场景以及优缺点。

一、基本步骤贪心算法的基本步骤可概括为:定义最优解的性质->利用贪心策略获得局部最优解->将局部最优解合并成一个整体最优解。

具体来说,一般包括以下几个步骤:1. 确定问题的最优解性质:要知道问题的最优解应该具有怎样的性质或特征,这些性质可以用于判断一个解是否符合规则或结果是否符合要求。

2. 构造候选解集:根据最优解的性质,不断构造可行的候选解集合,并通过一定的方法筛选出其中的解。

3. 选择最优解:从候选解集中选择一个最优解。

4. 验证最优解:通过验证最优解是否合法(满足约束条件)以及是否为问题的最优解,来验证贪心策略的正确性。

二、实现方式贪心算法的实现方式是比较灵活的,有些问题可以通过贪心策略来解决,有些则不行。

一般而言,如果问题的最优解具有贪心选择性质(即每一步的局部最优解能导致全局最优解),则采用贪心策略是可行的。

对于一些场景,我们可以通过规律来得到贪心策略。

例如:1. 集合覆盖问题:从未被覆盖的地方中选择一个覆盖点集最大的点,并删除所有覆盖的集合;2. 分数背包问题:选择性价比最高的物品,先吸纳尽量多的物品,再考虑其他物品。

三、应用场景1. 背包问题:针对背包问题和其变种,常见的贪心策略有分数背包(与完全和01背包有区别)和完全背包问题;2. 活动安排问题:在一些课程、项目或活动间选择,使得能够安排最多活动;3. 区间选择问题:在一些区间间选择相互不重叠的区间,使得能够选出最大的区间数;4. 集合覆盖问题:在一些集合中选择最少的集合,使得能够覆盖所有元素。

四、优缺点优点:1. 算法简单:贪心算法通常比较简单,易于理解和实现;2. 运算速度快:其时间复杂度一般较低,运算速度很快;3. 可以作为其他算法的优化:贪心策略可以应用于其他算法的优化中。

缺点:1. 不一定能够得到最优解:贪心策略仅考虑当前的局部最优解,对于全局最优解可能产生影响;2. 单一性:贪心算法的结果是唯一的,难以应对变化条件的需要,一旦局部最优解不满足当前的情况,算法就会失去原先的效果;3. 实现困难:对于有些问题,贪心算法并不是很好实现,涉及到更多的问题分析和模型的构造。

贪心算法实验(最小生成树)

贪心算法实验(最小生成树)

算法分析与设计实验报告第一次附加实验附录:完整代码(贪心法)//贪心算法最小生成树prim算法#include<iostream>#include<fstream>#include<string>#include<time.h>#include<iomanip>using namespace std;#define inf 9999; //定义无限大的值const int N=6;template<class Type> //模板定义void Prim(int n,Type c[][N+1]);int main(){int c[N+1][N+1];cout<<"连通带权图的矩阵为:"<<endl;for(int i=1;i<=N;i++) //输入邻接矩阵{for(int j=1;j<=N;j++){cin>>c[i][j];}}cout<<"Prim算法最小生成树选边次序如下:"<<endl;clock_t start,end,over; //计算程序运行时间的算法start=clock();end=clock();over=end-start;start=clock();Prim(N,c); //调用Prim算法函数end=clock();printf("The time is %6.3f",(double)(end-start-over)/CLK_TCK); //显示运行时间cout<<endl;system("pause");return 0;}template<class Type>//参数为结点个数n,和无向带权图中各结点之间的距离c[][N+1]void Prim(int n,Type c[][N+1]){Type lowcost[N+1]; //记录c[j][closest]的最小权值int closest[N+1]; //V-S中点j在s中的最临接顶点bool s[N+1]; //标记各结点是否已经放入S集合¦s[1]=true;//初始化s[i],lowcost[i],closest[i]for(int i=2;i<=n;i++){lowcost[i]=c[1][i];closest[i]=1;s[i]=false;}for(int i=1;i<n;i++){Type min=inf;int j=1;for(int k=2;k<=n;k++)//找出V-S中是lowcost最小的顶点j{if((lowcost[k]<min)&&(!s[k]))//如果k的lowcost比min小并且k结点没有被访问{min=lowcost[k]; //更新min的值j=k;}}cout<<j<<' '<<closest[j]<<endl; //输出j和最邻近j的点s[j]=true; //将j添加到s中for(int k=2;k<=n;k++){if((c[j][k]<lowcost[k])&&(!s[k]))//s集合放进j后更新各结点的lowcost 的值{lowcost[k]=c[j][k];closest[k]=j;}}}}。

实验二 贪心算法

实验二  贪心算法

实验二贪心法(4学时)上机实验一般应包括以下几个步骤:(1)、准备好上机所需的程序。

手编程序应书写整齐,并经人工检查无误后才能上机。

(2)、上机输入和调试自己所编的程序。

一人一组,独立上机调试,上机时出现的问题,最好独立解决。

(3)、上机结束后,整理出实验报告。

实验报告应包括:题目、程序清单、运行结果、对运行情况所作的分析。

一、实验目的与要求1.掌握贪心法的基本思想方法;2.了解适用于用贪心法求解的问题类型,并能设计相应贪心法算法;3.掌握贪心算法复杂性分析方法分析问题复杂性。

二、实验内容:1、哈夫曼编码设需要编码的字符集为{d1, d2, …, dn},它们出现的频率为{w1, w2, …, wn},应用哈夫曼树构造最短的不等长编码方案。

设计贪心算法求解此哈夫曼编码方案;2、删数问题键盘输入一个高精度的正整数n(n<10位)去掉任意s个数字后剩下的数字按原左右次序组成一个新的正整数。

编程对给定的n和s,寻找一种方案,使得剩下的数最小。

3、贪心背包问题已知一个容量为M的包和n件物品, 每件物品的重量为w i, 效益值为p i. 若将物品i的一部分0≤x i≤1装入包中, 背包可得到p i x i的效益值增量. 要求找到一种装入物品的方案, 在不超过包的总容量前提下, 使包获得最大效益值。

三、实验步骤1.理解算法思想和问题要求;2.编程实现题目要求;3.上机输入和调试自己所编的程序;4.验证分析实验结果;5.整理出实验报告。

四、实验要求1)上述题目任选两道做。

2)独立完成程序代码的编写3)独立完成实验及实验报告附:实验报告的主要内容一.实验目的二.问题描述三.解题思路四.算法设计包含:数据结构与核心算法的设计描述、函数调用及主函数设计、主要算法流程图等五.程序调试及运行结果分析六.实验总结附录:程序清单(程序过长,只附主要部分)五、实验原理贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。

贪心算法总结

贪心算法总结

贪心算法总结什么是贪心算法?贪心算法(Greedy Algorithm)是一种用于求解优化问题的常见算法,其核心思想是在每一步都选择当前最优解,希望最终能够得到全局最优解。

贪心算法在每一步仅考虑局部最优,而不关心全局最优,因此它的计算速度较快。

然而,由于贪心算法没有考虑全局,在某些情况下可能无法得到最优解。

贪心算法并不适用于所有的问题,只适用于一些特殊的问题,例如背包问题、最小生成树问题等。

在实际应用中,需要根据具体问题的特点来判断是否可以使用贪心算法来解决。

贪心算法的基本思路贪心算法的基本思路可以概括为以下几步:1.确定最优解的性质:首先要确定在每一步选择中,能够得到局部最优解。

2.构造贪心选择:根据最优解的性质,每一步都做出一个贪心选择,选择能够获得当前最大或最小收益的方案。

3.确定限制条件:确定问题的限制条件,包括物品的容量、时间限制等。

4.根据限制条件,进行剪枝策略:如果某种选择在限制条件下无法满足要求,则需要进行剪枝,排除该选择。

5.循环执行贪心选择,直到问题得到解决。

贪心算法的优缺点贪心算法具有以下优点:•计算速度快:贪心算法在每一步只考虑局部最优解,不需要对全局进行搜索,因此计算速度较快。

•算法思路简单:贪心算法的思路相对简单,易于理解和实现。

•适用范围广:贪心算法适用于一些特殊问题,如最短路径、最小生成树等。

然而,贪心算法也存在一些缺点:•可能无法得到最优解:由于贪心算法仅考虑局部最优解,而不关心全局最优解,因此可能无法得到最优解。

•需要满足贪心选择性质:贪心算法要求问题具有贪心选择性质,即每一步都能够得到局部最优解。

如果问题不具备这个性质,贪心算法可能不适用。

贪心算法的应用场景贪心算法适用于一些特殊的问题,以下是一些常见的应用场景:1. 最短路径问题最短路径问题是指在一个加权有向图中,找出从一个顶点到另一个顶点的最短路径。

贪心算法可以用来解决一些简单的最短路径问题,如Dijkstra算法。

贪心算法实验报告(C语言)

贪心算法实验报告(C语言)

实验2、《贪心算法实验》一、实验目的1. 了解贪心算法思想2. 掌握贪心法典型问题,如背包问题、作业调度问题等。

二、实验内容1. 编写一个简单的程序,实现单源最短路径问题。

2. 编写一段程序,实现找零。

【问题描述】当前有面值分别为2角5分,1角,5分,1分的硬币,请给出找n分钱的最佳方案(要求找出的硬币数目最少)。

3. 编写程序实现多机调度问题【问题描述】要求给出一种作业调度方案,使所给的n个作业在尽可能短的时间内由m 台机器加工处理完成。

约定,每个作业均可在任何一台机器上加工处理,但未完工前不允许中断处理。

作业不能拆分成更小的子作业。

三、算法思想分析1.初始化将源点设计为红点集,其余点设计为蓝点,重复选择蓝点集中与源点路径最短的点加入红点集,更新剩余的蓝点集路径,直至蓝点集为空或者只剩下没有连通的点,那么源点到其余所有点的最短路径就出来了。

2.找零问题是典型的贪心问题,但是并不代表所有的找零都能用贪心算法找到最优解。

只有满足贪心选择性质的找零才能找到最优解,本题满足贪心选择性质,直接先一直选面值最大的硬币,再一次减小即可。

3.先对作业按时长进行重排序,再依次找目前用时最短的机器安排工作并加上对应时长,最后总时长为机器中用时最长的那个时长。

四、实验过程分析1.单源最短路径的算法思想并不难,但是在实际编码过程中还是有很多小问题需要注意,首先,一定要新建数组存储路径变化,因为后面计算路径时会用到原数组,如果直接在原数组上更改后面就找不到原数据了,那么就会出现偏差。

其次就是建议先写个伪代码,判断的if-else语句比较多,容易搞混,在代码中一定要及时备注,某些代码的功能是什么,不然再次看代码时需要思考很久甚至忘记。

2.找零问题直接用while循环或者不断取余取模即可解决。

3.作业调度问题大致分为三步,一是排序,二是不断找最短时长的机器安排作业,三是找最长时间为作业完成时间。

五、算法源代码及用户屏幕1.(1)算法源码/**********************单源最短路径问题。

贪心算法策略与实现及代码示例

贪心算法策略与实现及代码示例

贪心算法策略与实现及代码示例贪心算法(Greedy algorithm)是一种常见的算法策略,用于在求解最优化问题时进行近似解的寻找。

该算法的核心思想是每一步都采取当前状态下最优的选择,希望能够通过局部最优解的累积达到全局最优解。

贪心算法的设计步骤一般包括以下几个关键步骤:1. 确定问题的最优子结构:要利用贪心算法求解问题,必须首先确定问题是否具有最优子结构的特性,即问题的最优解包含其子问题的最优解。

2. 找到最优子结构的贪心选择性质:通过一种贪心的方式来选择某个步骤的局部最优解,以期望最终能够得到全局最优解。

3. 证明贪心选择性质的正确性:需要证明选择的贪心策略是正确的,即选择的每一步都不会导致最终解的劣化。

4. 设计递归算法:将问题划分为更小的子问题,并通过递归的方式解决。

5. 实现贪心算法:根据贪心策略设计算法实现,通常使用迭代的方式进行求解。

下面以一个具体的问题来说明贪心算法的策略与实现,并给出相应的代码示例。

问题描述:给定一组活动,每个活动都有开始时间和结束时间,你需要选择出最多的互不相交的活动。

贪心算法策略:根据活动的结束时间,选择结束时间最早的活动进行安排。

代码实现(Python):```pythondef greedy_activity_selection(start, finish):n = len(start)selected = []selected.append(0) # 选择第一个活动j = 0for i in range(1, n):if start[i] >= finish[j]:selected.append(i)j = ireturn selected# 测试数据start_time = [1, 3, 2, 5, 8, 5]finish_time = [2, 4, 6, 7, 9, 9]selected_activities = greedy_activity_selection(start_time, finish_time) print("Selected activities:")for i in selected_activities:print("Activity", i+1)```代码示例中的`greedy_activity_selection`函数实现了贪心算法选择活动的过程。

贪心算法实验python

贪心算法实验python

南阳理工学院算法设计与分析报告册开课学院:计算机与信息工程学院实验项目:贪心算法实验实验时间:实验地点:指导教师:学生姓名:学生学号:专业班级: 18大数据2019-2020学年第2学期一、实验目的1.了解贪心算法思想及基本原理2.掌握使用贪心算法求解问题的一般特征3.能够针对实际问题,能够正确选择贪心策略。

4.能够针对选择的贪心策略,证明算法的正确性。

5.能够根据贪心策略,正确编码。

6.能够正确分析算法的时间复杂度和空间复杂度二、实验平台1.Windows操作系统或Linux操作系统2.Python3.x3.pyCharm或sublime或jupyter notebook三、实验内容最优服务次序问题:设有n个顾客同时等待一项服务。

顾客i需要的服务时间为ti,1≤i≤n。

共有s处可以提供此服务。

应如何安排n个顾客的服务次序才能使平均等待时间达到最小平均等待时间是n个顾客等待服务时间的总和除以n。

四、算法设计1.问题分析根据贪心思想,哪位顾客服务所需的时间短,就先服务那个顾客,然后依次类推,每次都是首先服务所需时间短的,这样能保证等待时间最短。

2.问题建模输入;集合s={1,2,3,...,n},第i个顾客的服务时间;输出:第i个顾客的等待时间目标函数:SUM(每个顾客的等待时间)/总顾客的数,得到平均等待时间3.算法描述首先保存每位顾客的服务时间到数组,然后把服务时间使用冒泡排序按照从小到大排序,然后遍历数组,服务时间最小的先服务,然后其次被服务的顾客的等待时间为(上一位顾客的服务时间和自己的被服务时间)最后求出总的服务时间在除以总顾客数得到最小平均等待时间。

五、算法源码def waitime(n):a=[0 for i in range(0,n)]#定义一个数组并将n个服务时间存进数组a for i in range(0,len(a)):a[i]=int(input(("请输入顾客需要的服务时间:")))for i in range(0, len(a) - 1): # 冒泡排序,将这n个服务时间从小到大排序for j in range(0, len(a) - i - 1):if (a[j] > a[j + 1]):a[j], a[j + 1] = a[j + 1], a[j]sum=a[0]#排完序后第一个最先开始for i in range(1,len(a)):a[i]=a[i]+a[i-1]sum=sum+a[i]time=sum/n#求出最小平均等待时间print("最小平均等待时间是:",time)if __name__ == "__main__":n=int(input(("请输入顾客个数:")))waitime(n)六、测试数据请输入顾客个数:4分别为:2 3 5 1最小平均等待时间是: 5.25七、程序运行结果(要求:截图说明算法运行的结果)八、算法分析(分析算法的时间复杂度和空间复杂度)时间复杂度:程序进行了一次排序(O(nlogn))和循环(O(n)),故时间复杂度为O(nlogn);空间复杂度:程序定义了一个一维数组(lengh_n[n])用于存放每个程序的大小,故时间复杂度为O(n)。

算法分析与设计实验二贪心算法

算法分析与设计实验二贪心算法

算法分析与设计实验二贪心算法贪心算法(Greedy Algorithm)是一种常用的算法设计方法,其核心思想是在每一步都做出当前情况下最优选择,以期望最终得到全局最优解。

本实验主要介绍贪心算法的原理、应用和分析。

一、贪心算法的原理贪心算法的基本思路是在每一步都做出当前情况下最优选择,并且不考虑当前选择对后续选择的影响。

贪心算法通常采用贪心选择策略和最优子结构两个基本要素。

1.贪心选择策略贪心选择策略是指在每一步都选择当前情况下最优解的策略。

这种策略要求我们能够证明,通过选择当前最优解,可以使得问题的规模减小到原问题的一个子问题,并且该子问题的最优解一定包含在全局最优解中。

2.最优子结构最优子结构是指问题的最优解包含其子问题的最优解。

贪心算法求解问题的过程通常包括两个步骤,选择最优子结构和利用最优子结构得到最优解。

二、贪心算法的应用1.集合覆盖问题集合覆盖问题是指在给定的一组集合中,找出最小的子集合,使得这些子集合的并集包含所有的元素。

贪心算法可以通过每一步选择包含最多未覆盖元素的集合,直到覆盖所有元素为止。

2.挑选活动问题挑选活动问题是指在给定一组活动的起始时间和结束时间,找出最大的相容活动子集合。

贪心算法可以通过每一步选择结束时间最早的活动,之后将该活动与其他相容的活动进行比较,从而得到最大的相容活动子集合。

3.分数背包问题分数背包问题是指在给定一组物品和一个背包容量的情况下,选择部分物品放入背包,使得放入背包的物品总价值最大。

贪心算法可以通过每一步选择单位重量价值最高的物品,直到背包容量不足为止。

三、贪心算法的分析贪心算法通常具有高效性和近似最优性的特点。

由于贪心算法每一步都选择当前最优解,不进行回溯和剪枝的操作,因此贪心算法的时间复杂度较低。

然而,贪心算法并不总能得到问题的最优解,它通常只能得到近似最优解。

贪心算法的近似性证明可以分为两步。

首先,我们需要证明贪心选择策略的正确性,即每一步选择的最优解一定包含在全局最优解中。

算法分析与设计实验二贪心算法

算法分析与设计实验二贪心算法

算法分析与设计实验二贪心算法贪心算法是一种基于贪心策略的求解问题的方法,该方法在每一步都采取最优的选择,从而最终得到全局最优解。

本实验将介绍贪心算法的概念、特点以及实际应用。

1.贪心算法的概念和特点贪心算法是一种求解问题的策略,它在每一步都做出局部最优选择,以期望最终得到全局最优解。

它不考虑每一步选择的长远影响,而只关注眼前能得到的最大利益。

贪心算法有以下特点:1.1.子问题的最优解能够推导父问题的最优解:贪心算法解决的问题具有最优子结构,即问题的最优解包含其子问题的最优解。

1.2.贪心选择性质:通过选择当前最优解,可以得到局部最优解。

1.3.无后效性:当前选择的最优解不会对以后的选择产生影响。

2.实际应用2.1.背包问题背包问题是一个经典的优化问题,贪心算法可以用于解决背包问题的一种情况,分数背包问题。

在分数背包问题中,物品可以被分割成任意大小,而不仅仅是0和1两种状态,因此可以通过贪心算法求解。

2.2.最小生成树问题最小生成树问题是求解连通带权图的一种最优生成树的问题。

其中,普里姆算法和克鲁斯卡尔算法就是贪心算法的典型应用。

2.3.哈夫曼编码哈夫曼编码是一种用于对信息进行无损压缩的方法,它可以将出现频率较高的字符用较短的二进制编码表示。

贪心算法可以在构建哈夫曼树的过程中选择出现频率最低的两个字符进行合并。

3.贪心算法的设计步骤3.1.理解问题并找到最优解的子结构。

3.2.根据问题特点设计贪心策略。

3.3.利用贪心策略进行求解,并逐步推导得到全局最优解。

3.4.对求得的解进行检验,确保其满足问题的要求。

4.贪心算法的优缺点4.1.优点:贪心算法简单直观,易于实现和理解;对于一些问题,贪心算法可以得到全局最优解。

4.2.缺点:贪心算法无法保证得到问题的全局最优解;贪心策略的选择可能不唯一综上所述,贪心算法是一种基于贪心策略的求解问题的方法,通过每一步的局部最优选择,期望得到全局最优解。

贪心算法具有明显的优点和缺点,在实际应用中可以有效地解决一些问题。

贪心算法求债权匹配问题

贪心算法求债权匹配问题

贪心算法求债权匹配问题1. 问题描述债权匹配问题是指在一组债务人和债权人之间,如何合理地分配债务,使得债务人的债务得到最大程度的满足,债权人的债权得到最大程度的回收。

贪心算法是一种常用的解决债权匹配问题的方法。

在债权匹配问题中,有n个债务人和m个债权人。

每个债务人都有一个债务金额,每个债权人都有一个债权金额。

债务人和债权人之间存在一种债权关系,债务人可以向债权人借款,债权人可以向债务人追债。

债务人和债权人之间的债权关系可以表示为一个二维矩阵C,其中C[i][j]表示债务人i向债权人j借款的金额。

债权匹配问题的目标是找到一个债权匹配方案,使得债务人的债务得到最大程度的满足,债权人的债权得到最大程度的回收。

具体来说,就是找到一个债权匹配方案,使得所有债务人的债务金额之和最大,同时所有债权人的债权金额之和最大。

2. 贪心算法求解贪心算法是一种常用的解决债权匹配问题的方法。

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

贪心算法求解债权匹配问题的具体步骤如下:2.1 构建债权关系图首先,根据债权关系矩阵C,构建债权关系图G。

债权关系图G是一个有向加权图,其中每个债务人和债权人都表示为一个节点,债务金额表示为节点的权重。

债权关系图G的边表示债权关系,边的权重表示债权金额。

2.2 初始化债权匹配方案初始化债权匹配方案为空。

债权匹配方案是一个集合,其中每个元素表示一对债务人和债权人的匹配关系。

2.3 贪心选择债权匹配从债权关系图G中选择一个债权匹配,使得当前债务人的债务金额最大,同时当前债权人的债权金额最大。

将这个债权匹配加入到债权匹配方案中。

2.4 更新债权关系图更新债权关系图G,将所有与已选择的债权匹配相关的债务人和债权人的债权关系移除。

2.5 重复步骤2.3和2.4重复步骤2.3和2.4,直到债权关系图G为空或者无法找到更多的债权匹配。

2.6 输出债权匹配方案输出债权匹配方案,即债权匹配方案中的所有债权匹配。

简述贪心算法的一般解题步骤

简述贪心算法的一般解题步骤

简述贪心算法的一般解题步骤一、基本步骤,贪心算法的一般解题步骤二、局部搜索算法。

在已知区域内设置一定数量的门槛值,初始化时,从每个门限值开始,沿着所有的可能走向探求一条满足要求的最佳路径,然后把这条最佳路径作为整个搜索区域的一部分进行搜索。

三、连续搜索算法。

进入每一个边界,从每一个可能的出口出发,按照边界上已经设置好的各种开关进行多次尝试,直到找到某种方案为止,该方案就是该边界的一种最优解。

其他可以通过边界信息调整变化的可能路径称为其他可选路径。

算法1:(1)将被测空间分成互不相交的四个区域。

(2)每个子集A与B分别设为当前搜索的出发点和回到点,即A={-1};B={1}。

(3)根据所需解决的问题及性质,确定应使用的门限值的数目。

(4)将第(3)条中的{-1}、{1}设为给定的初始门限值。

(5)假定只有当N=N0时才停止进行下一步,则有m=1, 2,…, N(6)采用多重线性搜索或递归算法寻找P(N|M)=N*M的解。

4.提取有用的最大元素。

由有用的最大元素作为最优决策边界的一部分。

通常用给定的数目(N)提取有用的最大元素,然后按照各子边界上有用的最大元素数目提取更多的有用最大元素。

(7)修改并检验各边界的决策。

用初始门限值(0)、(1)、(2)、(3)对各边界加权计算它们的平均有用的最大元素;利用累积的结果来估计各个边界的实际决策值。

(8)返回决策边界。

(9)执行下一步。

(10)反复执行,直至遇到阻碍为止。

5.由有用的最大元素作为最优决策边界。

(11)再做一次加权平均运算,得到新的决策边界,如此继续循环下去,直至达到预期的终点。

(12)判断总体性能。

根据最小费用原理和不等式约束条件,求出各个子边界的决策值之和是否等于母边界的决策值。

若是,说明此方案比较适合(当前)状态;否则需要重新制定决策。

算法分析与设计实验二贪心算法

算法分析与设计实验二贪心算法

算法分析与设计实验二贪心算法实验二:贪心算法【实验目的】应用贪心算法求解活动安排问题。

【实验性质】验证性实验。

【实验要求】活动安排问题是可以用贪心算法有效求解的很好的例子。

问题:有n个活动的集合A={1,2,…,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。

求解:安排尽量多项活动在该场地进行,即求A的最大相容子集。

设待安排的11个活动的开始时间和结束时间按结束时间的升序排列如下: i 1 2 35 3 06 4 57 5 38 6 59 7 6 10 8 8 11 9 8 12 10 2 13 11 12 14 s[i] 1 f[i] 4将此表数据作为实现该算法的测试数据。

【算法思想及采用的数据结构】【程序代码】【运行结果】【算法分析和心得体会】附加题:【实验要求】需要在某个城市的n个居民区之间铺设煤气管道,则在这n个居民区之间只要铺设n-1条管道即可。

假设任意两个居民区之间都可以架设管道,但由于地理环境的不同,所需经费不同。

选择最优的施工方案能使总投资尽可能少,这个问题即为求网的“最小生成树”问题。

参照以下居民区示意图,使得求解算法为:在可能架设的m条管道中选取n-1条,既能连通n-1个居民区,有使总投资达到“最小”。

网可采用邻接矩阵为存储结构,以定点对(i,j)的形式输出最小生成树的边。

D 23.1 675.9 C 41.1 56B A 38.2 441218.2 I 8.7 H 52.5 G 10.5E 98.7 居民区示意图 85F 79应用贪心算法策略,采用普里姆算法或Kruskal算法来求解居民区示意图的最小生成树,采用合适的数据结构。

用C语言或C++语言编写程序代码,选上述居民区示意图中的数据作为测试数据。

并调试输出正确结果。

【算法思想及采用的数据结构】【程序代码】【运行结果】【算法分析和心得体会】感谢您的阅读,祝您生活愉快。

实验二贪心算法

实验二贪心算法
它采用自顶向下以迭代的方法做出相继的贪心选择每做一次贪心选择就将所求问题简化为一个规模更小的子问题通过每一步贪心选择可得到问题的一个最优解虽然每一步上都要保证能获得局部最优解但由此产生的全局解有时不一定是最优的所以贪婪法不要回溯
一、实验目的
1. 运用背包问题解决具体问题 2. 培养编程与上机调试能力
程序实现
完成程序的编程和调试,输出正确结果 (仅供参考)
实例
实例
三、实验原理

贪心算法是指,在对问题求解时,总是做出在当前看 来是最好的选择,不从整体最优上加以考虑,所做出 的仅是在某种意义上的局部最优解。 贪心算法(Greedy algorithm)是一种对某些求最优解 问题的更简单、更迅速的设计技术。它采用自顶向下, 以迭代的方法做出相继的贪心选择,每做一次贪心选 择就将所求问题简化为一个规模更小的子问题 , 通过 每一步贪心选择,可得到问题的一个最优解,虽然每 一步上都要保证能获得局部最优解,但由此产生的全 局解有时不一定是最优的,所以贪婪法不要回溯。
二、实验内容
实现背包问题的贪心算法 己知一个容量为M的背包。现在要从n种物品中选 取若干装入背包中,每种物品的重量为w(i) 、价 值为p(i) 。定义一种可行的背包装载为:背包中物 品的总重量不能超过背包的容量,每种物品仅有 一件,可以选择放或不放。采取怎样的装包方案 才会使装入背包的物品价值总和最大? 考虑:如果物品可分割,算法如何实现(选做)。
有解元素组合成问题的一个可行解。

该算法存在问题: 1、不能保证求得的最后解是最佳的; 2、不能用来求最大或最小解问题; 3、只能求满足某些约束条件的可行解的范围。
四、实验步骤
1、设计算法; 2、采用高级语言实现该算法; 3、调试程序,检查输出结果。

算法分析与设计实验报告--贪心法 (2)

算法分析与设计实验报告--贪心法 (2)
例1已知如下图所示的单行线交通网,每弧旁的数字表示通过这条单行线所需要的费用,现在某人要从v1出发,通过这个交通网到v8去,求使总费用最小的旅行路线。
Dijkstra方法的基本思想是从vs出发,逐步地向外探寻最短路。执行过程中,与每个点对应,记录下一个数(称为这个点的标号),它或者表示从vs到该点的最短路的权(称为P标号)、或者是从vs到该点的最短路的权的上界(称为T标号),方法的每一步是去修改T标号,并且把某一个具T标号的改变为具P标号的点,从而使G中具P标号的顶点数多一个,这样至多经过n-1(n为图G的顶点数)步,就可以求出从vs到各点的最短路。
if(D[j]>D[min]+graph[min][j]||D[j]==-1)
{D[j]=D[min]+graph[min][j]; //每次迭代求最小值,最后一次即为到源点的最短路径
P[j]=min;
}
}
}
void main()
{instital(R, B, D, P);
theshortestway(R, B, D, P);
using namespace std;
int const ZUSHU = 5;
int Ling[] = {50,20,10,5,1};
int GeShu[ZUSHU];
void ZhaoLing(int n)
{for(int i=0;i<ZUSHU;i++)
{GeShu[i] = n / Ling[i];n = n % Ling[i];}
(1)初始时,S中仅含有源节点。
(2)设u是G的某一个顶点,把从源到u且中间只经过S中顶点的路称为从源到u的特殊路径,用数组D[i]记录顶点i当前所对应的最短特殊路径长度。

实验二 贪心算法-最少活动会场安排问题

实验二   贪心算法-最少活动会场安排问题

中原工学院计算机学院实验报告实验项目名称实验二、最少活动会场安排问题课程名称算法设计与分析学生姓名梁斐燕学生学号************所在班级网络14卓越学科专业网络工程任课教师吴志刚完成日期2016年月日实验二最少活动会场安排问题一、实验目的1.掌握贪心算法的基本概念和两个基本要素2.熟练掌握贪心算法解决问题的基本步骤。

3.学会利用贪心算法解决实际问题。

二、实验内容•问题描述:•题目一:假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。

设计一个有效的贪心算法来进行安排,试编程实现。

•题目二:一辆汽车加满油后,可行使n千米。

旅途中有若干个加油站。

若要使沿途加油次数最少,设计一个有效算法,指出应在哪些加油站停靠加油。

•数据输入:个人设定,由键盘输入。

•要求:–上述题目任选一做。

上机前,完成程序代码的编写–独立完成实验及实验报告三、实验步骤㈠、数据结构与核心算法的设计描述提示:题目一:参考教材活动安排问题;有关队列操作参考数据结构。

void GreedySelector(int n, int *s, int *f, int *A) {//用集合A来存储所选择的活动A[1] = TURE; //默认从第一次活动开始执行int j = 1; //j记录最近一次加入到A中的活动for (int i = 2; i <= n; i++) { //f[j]为当前集合A中所有活动的最大结束时间//活动i的开始时间不早于最近加入到集合A中的j的时间f[j]if (s[i] >= f[j]) {A[i] = TURE; //当A[i]=TURE时,活动i在集合A中j = i;}else A[i] = FALSE;}}㈡、函数调用及主函数设计㈢程序调试及运行结果分析㈣实验总结在做本实验之前,自己看了课本上所列举的贪心法解活动安排问题的代码,代码很简单,很容易理解,于是就按课本的代码实现。

通过几个测试用例测试发现结果不对,后来发现自己忘了进行贪心法的一个前提条件,事先没有按各个活动结束时间对所有活动进行非递减排序,所以才会导致结果错误。

实验二(贪心算法)

实验二(贪心算法)

华东师范大学计算机科学技术系上机实践报告课程名称:算法设计与分析年级:05上机实践成绩:指导教师:柳银萍姓名:张翡翡上机实践名称:贪心算法学号:10052130119上机实践日期:2007-4-10上机实践编号:NO.2组号:上机实践时间:10:00-11:30一、目的了解熟悉掌握贪心算法实质并学会灵活运用,从而解决生活中一些实际问题。

二、内容与设计思想1.超市的自动柜员机(POS)要找给顾客各种数值的现金,表面上看,这是一个很简单的任务,但交给机器办就不简单了。

你作为一个计算机专家,要求写一个程序来对付这个“简单”的问题。

你的自动柜员机有以下的币种:100元,50元,20元,10元,5元,2元,1元。

你可以假设每种钱币的数量是无限的。

现在有一笔交易,需要找个客户m元,请你设计一个算法,使得找给顾客的钱币张数最少。

要求:输入:第一行仅有一个整数n(0<n<=10000),表示有几组测试数据。

每组测试数据仅有一行,每行只有一个整数m(0<m<2000000000),表示需要找的钱币数。

(提示:对于大量的输出,请使用scanf,不要使用cin)输出:每组测试数据输出一行,每行有7个整数(两两之间有一个空格,结尾不能有空格),表示100元,50元,20元,10元,5元,2元,1元所需要的张数。

1.1其思路是:1)定义相关变量;2)接收相关数据,如测试数据组数n和要找的钱币数;3)依次考虑100,50,20,10,5,2,1的需要找的钱币张数,用最简单的加减乘除;4)输出其值。

1.2具体算法是:while(n--)m 输入a=m/100b=(m-100*a)/50c=(m-100a-50b)/20d=(m-100a-50b-20c)/10e=(m-100a-50b-20c-10d)/5f=(m-100a-50b-20c-10d-5e)/2g=m-100a-50b-20c-10d-5e-2fend while2.若在0-1背包问题中各物品是依重量递增排列时,其价值恰好依递减序排列。

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

实验二贪心法(4学时)上机实验一般应包括以下几个步骤:(1)、准备好上机所需的程序。

手编程序应书写整齐,并经人工检查无误后才能上机。

(2)、上机输入和调试自己所编的程序。

一人一组,独立上机调试,上机时出现的问题,最好独立解决。

(3)、上机结束后,整理出实验报告。

实验报告应包括:题目、程序清单、运行结果、对运行情况所作的分析。

一、实验目的与要求1.掌握贪心法的基本思想方法;2.了解适用于用贪心法求解的问题类型,并能设计相应贪心法算法;3.掌握贪心算法复杂性分析方法分析问题复杂性。

二、实验内容:1、哈夫曼编码设需要编码的字符集为{d1, d2, …, dn},它们出现的频率为{w1, w2, …, wn},应用哈夫曼树构造最短的不等长编码方案。

设计贪心算法求解此哈夫曼编码方案;2、删数问题键盘输入一个高精度的正整数n(n<10位)去掉任意s个数字后剩下的数字按原左右次序组成一个新的正整数。

编程对给定的n和s,寻找一种方案,使得剩下的数最小。

3、贪心背包问题已知一个容量为M的包和n件物品, 每件物品的重量为w i, 效益值为p i. 若将物品i的一部分0≤x i≤1装入包中, 背包可得到p i x i的效益值增量. 要求找到一种装入物品的方案, 在不超过包的总容量前提下, 使包获得最大效益值。

三、实验步骤1.理解算法思想和问题要求;2.编程实现题目要求;3.上机输入和调试自己所编的程序;4.验证分析实验结果;5.整理出实验报告。

四、实验要求1)上述题目任选两道做。

2)独立完成程序代码的编写3)独立完成实验及实验报告附:实验报告的主要内容一.实验目的二.问题描述三.解题思路四.算法设计包含:数据结构与核心算法的设计描述、函数调用及主函数设计、主要算法流程图等五.程序调试及运行结果分析六.实验总结附录:程序清单(程序过长,只附主要部分)五、实验原理贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。

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

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

A、贪心算法的基本思路1.建立数学模型来描述问题。

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

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

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

B、实现该算法的过程:从问题的某一初始解出发;while 能朝给定总目标前进一步do求出可行解的一个解元素;由所有解元素组合成问题的一个可行解。

C、贪心算法的适用的问题:贪心算法适用的问题必须满足两个属性:(1)贪心性质:整体的最优解可通过一系列局部最优解达到,并且每次的选择可以依赖以前做出的选择,但不能依赖于以后的选择。

(2)最优子结构:问题的整体最优解包含着它的子问题的最优解。

D、贪心算法的基本步骤(1)分解:将原问题分解为若干相互独立的阶段。

(2)解决:对于每一个阶段求局部的最优解。

(3)合并:将各个阶段的解合并为原问题的解。

附注:部分实验代码1、哈夫曼编码数据结构与算法typedef char *HuffmanCode; //动态分配数组,存储哈夫曼编码typedef struct{unsigned int weight; //用来存放各个结点的权值unsigned int parent,LChild,RChild; //指向双亲、孩子结点的指针} HTNode, *HuffmanTree; //动态分配数组,存储哈夫曼树核心源代码#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct{unsigned int weight; //用来存放各个结点的权值unsigned int parent,LChild,RChild; //指向双亲、孩子结点的指针} HTNode, *HuffmanTree; //动态分配数组,存储哈夫曼树typedef char *HuffmanCode; //动态分配数组,存储哈夫曼编码//选择两个parent为0,且weight最小的结点s1和s2void Select(HuffmanTree *ht,int n,int *s1,int *s2){int i,min;for(i=1; i<=n; i++){if((*ht)[i].parent==0){min=i;break;}}for(i=1; i<=n; i++){if((*ht)[i].parent==0){if((*ht)[i].weight<(*ht)[min].weight)min=i;}}*s1=min;for(i=1; i<=n; i++){if((*ht)[i].parent==0 && i!=(*s1)){min=i;break;}}for(i=1; i<=n; i++){if((*ht)[i].parent==0 && i!=(*s1)){if((*ht)[i].weight<(*ht)[min].weight)min=i;}}*s2=min;}//构造哈夫曼树ht,w存放已知的n个权值void CrtHuffmanTree(HuffmanTree *ht,int *w,int n){int m,i,s1,s2;m=2*n-1; //总共的结点数*ht=(HuffmanTree)malloc((m+1)*sizeof(HTNode));for(i=1; i<=n; i++) //1--n号存放叶子结点,初始化{(*ht)[i].weight=w[i];(*ht)[i].LChild=0;(*ht)[i].parent=0;(*ht)[i].RChild=0;}for(i=n+1; i<=m; i++) //非叶子结点的初始化{(*ht)[i].weight=0;(*ht)[i].LChild=0;(*ht)[i].parent=0;(*ht)[i].RChild=0;}printf("\n哈夫曼树为: \n");for(i=n+1; i<=m; i++) //创建非叶子结点,建哈夫曼树{ //在(*ht)[1]~(*ht)[i-1]的范围内选择两个parent为0且weight最小的结点,其序号分别赋值给s1、s2Select(ht,i-1,&s1,&s2);(*ht)[s1].parent=i;(*ht)[s2].parent=i;(*ht)[i].LChild=s1;(*ht)[i].RChild=s2;(*ht)[i].weight=(*ht)[s1].weight+(*ht)[s2].weight;printf("%d (%d, %d)\n",(*ht)[i].weight,(*ht)[s1].weight,(*ht)[s2].weight);}printf("\n");}//从叶子结点到根,逆向求每个叶子结点对应的哈夫曼编码void CrtHuffmanCode(HuffmanTree *ht, HuffmanCode *hc, int n){char *cd; //定义的存放编码的空间int a[100];int i,start,p,w=0;unsigned int c;hc=(HuffmanCode *)malloc((n+1)*sizeof(char *)); //分配n个编码的头指针cd=(char *)malloc(n*sizeof(char)); //分配求当前编码的工作空间cd[n-1]='\0'; //从右向左逐位存放编码,首先存放编码结束符for(i=1; i<=n; i++) //求n个叶子结点对应的哈夫曼编码{a[i]=0;start=n-1; //起始指针位置在最右边for(c=i,p=(*ht)[i].parent; p!=0; c=p,p=(*ht)[p].parent) //从叶子到根结点求编码{if( (*ht)[p].LChild==c){cd[--start]='1'; //左分支标1a[i]++;}else{cd[--start]='0'; //右分支标0a[i]++;}}hc[i]=(char *)malloc((n-start)*sizeof(char)); //为第i个编码分配空间strcpy(hc[i],&cd[start]); //将cd复制编码到hc}free(cd);for(i=1; i<=n; i++)printf(" 权值为%d的哈夫曼编码为:%s\n",(*ht)[i].weight,hc[i]);for(i=1; i<=n; i++)w+=(*ht)[i].weight*a[i];printf(" 带权路径为:%d\n",w);}void main(){HuffmanTree HT;HuffmanCode HC;int *w,i,n,wei;printf("**哈夫曼编码**\n" );printf("请输入结点个数:" );scanf("%d",&n);w=(int *)malloc((n+1)*sizeof(int));printf("\n输入这%d个元素的权值:\n",n);for(i=1; i<=n; i++){printf("%d: ",i);fflush(stdin);scanf("%d",&wei);w[i]=wei;}CrtHuffmanTree(&HT,w,n);CrtHuffmanCode(&HT,&HC,n);}2、删数问题#include<stdio.h>int Del(int D,int a[10],int n)//D 删除几位a 数组n 当前数组位数{int res,max,i,j,x[10];for(i=0;i<n;i++)x[i]=a[n-i-1];while(1){if(D==0)break;elseD--;max=0;j=0;for(i=0;i<n;i++){if(max<x[i]){max=x[i];j=i;}}n--;for(i=j;i<n;i++)x[i]=x[i+1];}res=0;for(i=0;i<n;i++)res=res*10+x[i];return(res); void main(){int Res,D,z,n,m,i,a[10];//m=43252556;i=0;n=0;printf("<------------------删数问题---------------------->\n");printf("请输入一个高精度的正整数N(N<=10位):");scanf("%d",&m);printf("请输入要去掉数字的位数S(S<=N):");scanf("%d",&D);while(1){z=m/10;a[i]=m-z*10;m=z;i++;n++;if(m==0)break;}Res=Del(D,a,n);printf("删除后的结果为:");printf("%d\n",Res);3贪心背包问题#include <iostream.h>#include<iomanip.h>#include<string.h>int min(int w,int c){int temp;if (w<c) temp=w;elsetemp=c;return temp;}int max(int w,int c){int temp;if (w>c) temp=w;elsetemp=c;return temp;}void knapsack(int v[],int w[],int c,int n,int**m) //求最优值{int jmax=min(w[n]-1,c);for(int j=0;j<=jmax;j++)m[n][j]=0;for(int jj=w[n];jj<=c;jj++)m[n][jj]=v[n];for(int i=n-1;i>1;i--){ //递归部分jmax=min(w[i]-1,c);for(int j=0;j<=jmax;j++)m[i][j]=m[i+1][j];for(int jj=w[i];jj<=c;jj++)m[i][jj]=max(m[i+1][jj],m[i+1][jj-w[i]]+v[i]);}m[1][c]=m[2][c];if(c>=w[1])m[1][c]=max(m[1][c],m[2][c-w[1]]+v[1]);cout<<"最优值:"<<m[1][c]<<endl;cout<<endl;}int traceback(int **m,int w[],int c,int n,int x[]) //回代,求最优解{cout<<"得到的一组最优解如下:"<<endl;for(int i=1;i<n;i++)if(m[i][c]==m[i+1][c]) x[i]=0;else {x[i]=1;c-=w[i];}x[n]=(m[n][c])?1:0;for(int y=1;y<=n;y++)cout<<setw(5)<<x[y]<<endl;return x[n];}void main(){int n,c;int **m;cout<<"请输入物品个数和重量上限:"; cin>>n>>c;int *v=new int[n+1];cout<<"请输入价值(v[i]):"<<endl;for(int i=1;i<=n;i++)cin>>v[i];int *w=new int[n+1];cout<<"请输入重量(w[i]):"<<endl;for(int j=1;j<=n;j++)cin>>w[j];int *x=new int[n+1];m=new int*[n+1]; //动态的分配二维数组for(int p=0;p<n+1;p++)m[p]=new int[c+1];knapsack(v,w,c,n,m);traceback(m,w,c,n,x);}。

相关文档
最新文档