贪心算法活动安排问题

合集下载

贪心法解活动安排问题(计算机算法设计与分析)

贪心法解活动安排问题(计算机算法设计与分析)

实验报告
课程名称:算法设计与分析实验名称:贪心法解活动安排问题任课教师:专业:计算机科学与技术
班级: 20xx 级x班学号:
姓名:完成日期: 20xx年x月xx日
五、实验总结
在做本实验之前,自己看了课本上所列举的贪心法解活动安排问题的代码,代码很简单,很容易理解,于是就按课本的代码实现。

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

经过修正后,自己真正理解了贪心法解活动安排问题的原理,重新完成本次实验内容也是很顺利,在编程方面没有遇到什么困难。

贪心法解活动安排问题(计算机算法设计与分析)

贪心法解活动安排问题(计算机算法设计与分析)

实验报告
课程名称:算法设计与分析实验名称:贪心法解活动安排问题任课教师:专业:计算机科学与技术
班级: 20xx 级x班学号:
姓名:完成日期: 20xx年x月xx日
五、实验总结
在做本实验之前,自己看了课本上所列举的贪心法解活动安排问题的代码,代码很简单,很容易理解,于是就按课本的代码实现。

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

经过修正后,自己真正理解了贪心法解活动安排问题的原理,重新完成本次实验内容也是很顺利,在编程方面没有遇到什么困难。

第4章 贪心算法(1)活动安排问题

第4章 贪心算法(1)活动安排问题
3
4.1 活动安排问题
活动安排问题是可以用贪心算法有效求解的很 好例子。
该问题要求高效地安排一系列争用某一公共资 源的活动,使得尽可能多的活动能兼容地使用 公共资源。
4
问题描述
设有n个活动的集合E={1, 2, …, n},其中每个 活动都要求使用同一资源,而在同一时间内只 有一个活动能使用这一资源。
2
贪心算法
例2:若上述硬币面值改为:
一角一分、五分和一分 现在要找给顾客一角五分钱,如何给出硬币? 答案:错:1个一角一分,4个一分
对:3个五分
虽然贪心算法不能对所有问题都得到整体最优 解,但对许多问题它能产生整体最优解。
在一些情况下,即使贪心算法不能得到整体最 优解,其最终结果却是最优解的很好的近似解。
ቤተ መጻሕፍቲ ባይዱ17
0-1背包问题
给定n种物品和一个背包。物品i的重量是wi, 其价值为vi,背包的容量为c。应如何选择装 入背包的物品,使得装入背包中物品的总价 值最大?
说明:在选择装入背包的物品时,对每种物 品i只有2种选择,即装入背包或不装入背包。 不能将物品i装入背包多次,也不能只装入部 分的物品i。
16
3、贪心算法与动态规划算法的 差异
贪心算法和动态规划算法都要求问题具有最 优子结构性质,这是两类算法的一个共同点。
对于具有最优子结构的问题应该选用贪心算 法还是动态规划算法求解?
是否能用动态规划算法求解的问题也能用贪 心算法求解?
下面研究2个经典的组合优化问题,并以此 说明贪心算法与动态规划算法的主要差别。
每个活动i都有一个要求使用该资源的起始时 间si和一个结束时间fi,且si <fi 。
5
问题描述
如果选择了活动i,则它在半开时间区间[si, fi) 内占用资源。若区间[si, fi)与区间[sj, fj)不相交, 则称活动i与活动j是相容的。也就是说,当si≥fj

贪心算法的常用范围

贪心算法的常用范围

贪心算法的常用范围一、什么是贪心算法?听我说,贪心算法其实就像你身边那些总是想着“现在最好的”那一类人。

啥意思呢?就是他们做事从来不考虑长远,只看眼前能捞多少,想法很简单,行动也特别直接。

比如说你去吃自助餐,眼前有一盘热腾腾的牛排,你只顾着夹那块,脑袋里想的就是“现在不吃,等下没了怎么办”。

这就有点像贪心算法,它在每一步选择中都追求局部的最优解。

问题是,这种做法能得出全局最优解吗?不一定哦。

所以,贪心算法适用的地方就有点挑剔,它只适合那些能通过局部最优解来推导出全局最优解的情况。

二、贪心算法的常见应用1. 活动安排问题咱们先来说个生活中常见的例子,活动安排问题。

假设你是一个忙碌的白领,今天有好多活动要参加,可惜你一整天的时间有限。

怎么安排才能把活动都参加个遍呢?如果你是那种贪心心态的家伙,你会选择哪个活动呢?肯定是选那些花费时间最少,能带来最大回报的活动嘛!简单粗暴的办法就像贪心算法一样,选择每一个最短时间的活动,把空余的时间都填满。

最终,你可能会发现,虽然你参加了很多活动,但并不一定能让你得到最大的收益。

所以说,这个问题就是一个典型的贪心算法的使用场景。

2. 找零问题还有个经典的例子是找零问题。

你去商店买东西,店员找给你零钱。

那如果你是商店的老板,应该怎么挑零钱呢?你肯定会选择把金额大的零钱先找给顾客吧,简单快捷又高效。

比如,顾客给你100块钱,你就找个50块、20块,再来几张5块,剩下的用1块来凑,最后一结账,顾客就满意地走了。

这个过程中,你是按照每次找最大的零钱进行选择,这就是贪心算法的一个典型应用。

找零问题背后就是一个在每一步都做出“局部最优选择”的过程,能够确保找到的零钱数量最少,操作也最为高效。

3. 最短路径问题再说个计算机里的例子,最短路径问题。

在一个图中,假如你是要从A点出发去B 点,你要怎么走才能最省力、最省时?这里的贪心算法会告诉你:每次从当前位置出发,选择一个最短的路径走,这样一步一步走下去,最后就能到达B点了。

贪心算法经典问题:活动安排,背包问题,最优装载,单源最短路径 Dijiksra,找零钱问题,多机调度

贪心算法经典问题:活动安排,背包问题,最优装载,单源最短路径 Dijiksra,找零钱问题,多机调度

活动安排public static int greedySelector(int [] s, int [] f, boolean a[]){ //s[]开始时间f[]结束时间int n=s.length-1;a[1]=true;int j=1;int count=1;for (int i=2;i<=n;i++){ if (s[i]>=f[j]) { a[i]=true; j=i; count++; }else a[i]=false;}return count;}背包问题void Knapsack(int n,float M,float v[],float w[],float x[]){ Sort(n,v,w); //以每种物品单位重量的价值Vi/Wi从大到小排序int i;for (i=1;i<=n;i++) x[i]=0;float c=M;for (i=1;i<=n;i++){ if (w[i]>c) break;x[i]=1;c-=w[i];}if (i<=n) x[i]=c/w[i]; //允许放入一个物品的一部分}最优装载void Loading(int x[], T ype w[], T ype c, int n){ int *t = new int [n+1]; //t[i]要存的是w[j]中重量从小到大的数组下标Sort(w, t, n); //按货箱重量排序for (int i = 1; i <= n; i++) x[i] = 0; //O(n)for (int i = 1; i <= n && w[t[i]] <= c; i++){x[t[i]] = 1; c -= w[t[i]];} //调整剩余空间}单源最短路径Dijiksratemplate<class Type>void Dijikstra(int n, int v, Type dist[], int prev[], Type **c){ //c[i][j]表示边(i,j)的权,dist[i]表示当前从源到顶点i的最短特殊路径bool s[maxint];for(int i= 1;i<=n; i++){ dist[i]=c[v][i]; s[i]=false;if(dist[i]==maxint) prev[i]=0;else prev[i]=v;}dist[v]=0 ; s[v]=true;for(int i=1;i<n;i++){ int temp = maxint, u = v;for(int j= 1;j<=n; j++)if( (!s[j])&&(dist[j]<temp) ){u= j ; temp=dist[j]; }s[u]= true;for(int j= 1;j<=n;j++)if( (!s[j])&&(c[u][j])<maxint){ Type newdist = dist[u]+c[u][j];if(newdist<dist[j]) {dist[j]= newdist; prev[j]=u; } }}//ENDFOR}//END找零钱问题#define NUM 4void main(){ int m[NUM]={25,10,5,1};int n; //假设n=99cin>>n;cout<<n<<"的找钱方案为:";for(int i=0;i<NUM;i++)while(n>=m[i]&&n>0){cout<<m[i]<<" ";n-=m[i];}}//END多机调度#define N 10#define M 3void sort(int t[],int n);int set_work1(int t[],int n);int max(int t[],int num);int min(int t[],int m);int set_work2(int t[],int n);static int time[N]={2,8,18,32,50,72,98,128,182,200},s[M]={0,0,0};void main(){sort(time,N);if(M>=N) //作业数小于机器数cout<<set_work1(time,N)<<endl;elsecout<<set_work2(time,N)<<endl;}void sort(int t[],int n){for(int k=0;k<n-1;k++) //用选择法将处理时间从大到小排序{int j=k;for (int i=k; i<n; i++)if (t[i]>t[j]) j=i;{int temp=t[j];t[j]=t[k];t[k]=temp;}}}int max(int t[],int num) //max函数求解处理时间总和最长{int max=t[0];for(int i=1;i<num;i++)if(max<t[i]) max=t[i];return max;}int min(int t[],int m){int min=0; //min记录目前处理作业时间和最小的机器号for(int i=1;i<m;i++)if(s[min]>s[i]) min=i;return min;}int set_work1(int t[],int n){ int m=0;for(int i=0;i<n;i++) //分派作业s[m++]+=t[i];return max(s,N);}int set_work2(int t[],int n){ for(int i=0;i<n;i++)s[min(s,M)]+=t[i];return max(s,M);}。

贪心算法(会场安排问题、区间选点)

贪心算法(会场安排问题、区间选点)

贪⼼算法(会场安排问题、区间选点)学习算法课程之后的第⼀次记录,渐渐的,程序设计考虑的因素增多,程序=数据结构+算法,这个等式让我深有体会。

从开始简单的C++编程,再到选择合适数据结构,现在需要更进⼀步,从算法层次上考虑程序执⾏的效率。

我对算法的理解是⽤更少的开销获得更优的执⾏效果。

分治法、动态规划在此之前没有记录下来,学到贪⼼算法的时候,觉得需要总结⼀下学过的东西,也能更好的理解。

动态规划的设计,要满⾜最优⼦结构性质和重叠⼦问题,采⽤⾃底向上的策略,计算出最优值,找到整体最优解。

这个过程有时候挺难的,主要在写出递归式,要⾃底向上填表。

贪⼼策略有点像动态规划,但在⼀些⽅⾯是不同的,有时候贪⼼算法的思想更容易想到。

它要满⾜⼦问题最优⽽得到整体最优?两个条件:最优⼦结构性质和贪⼼选择性质。

满⾜贪⼼选择性质⼀定满⾜最优⼦结构性质,⽽满⾜最优⼦结构性质不⼀定满⾜贪⼼选择性质,⽐如背包问题可以⽤贪⼼算法解决,⽽0-1背包问题只能⽤动态规划。

典型的贪⼼问题活动安排,有n个活动,给出开始时间和结束时间,要尽可能安排多的活动(时间互相不冲突)。

解决这个问题正确的贪⼼思想是以每个活动结束时间为⽐较变量,按结束时间升序排好活动次序,接着就进⾏⽐较选择。

⽽会场安排问题与活动⼜有些不同之处,下⾯是我的解题过程。

7-2 会场安排问题 (20 分)假设要在⾜够多的会场⾥安排⼀批活动,并希望使⽤尽可能少的会场。

设计⼀个有效的贪⼼算法进⾏安排。

(这个问题实际上是著名的图着⾊问题。

若将每⼀个活动作为图的⼀个顶点,不相容活动间⽤边相连。

使相邻顶点着有不同颜⾊的最⼩着⾊数,相应于要找的最⼩会场数。

)输⼊格式:第⼀⾏有 1 个正整数k,表⽰有 k个待安排的活动。

接下来的 k⾏中,每⾏有 2个正整数,分别表⽰ k个待安排的活动开始时间和结束时间。

时间以 0 点开始的分钟计。

输出格式:输出最少会场数。

输⼊样例:51 2312 2825 3527 8036 50输出样例:3#include<iostream>#include<algorithm>using namespace std;struct node {int begin;int end;int flag;//标记该活动是否被安排,0表⽰未安排,1表⽰已安排}t[10001];int cmp(const node &a,const node &b)//⽐较规则:以结束时间升序排列{return a.end<b.end;}int main(){int i,j,n;node temp;cin>>n;for(i=0;i<n;i++){cin>>t[i].begin>>t[i].end;t[i].flag=0;}sort(t,t+n,cmp);int sum=0;//总共需要的会场数量for(i=0;i<n;i++)//⽅法2{if(!t[i].flag)//找到未安排的活动,进⾏场地安排{sum++;int p=i;for(j=p+1;j<n;j++)//当前活动结束时间与下⼀个活动开始不相交,则安排到同⼀个会场{if(t[p].end<=t[j].begin&&!t[j].flag){p=j;t[j].flag=1;}}t[i].flag=1;}}cout<<sum;return0;}View Code贪⼼策略为:把尽可能多的时间互不冲突的活动安排到⼀个会场,若活动时间交叉,则在安排到另⼀个会场。

贪心法解决活动安排问题

贪心法解决活动安排问题

用贪心算法解决活动安排的问题3问题概述设有n个活动的集合E={1,2,……,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。

每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi,且si<fi。

如果选择了活动i,则它在时间区间[si,fi]内占用资源。

若区间[si,fi]与区间[sj,fj]不相交,则称活动i与活动j是相容的。

也就是说,当si>=fj或者sj>=fi时,活动i与活动j相容。

活动安排问题就是要在所给的活动集合中选出最大的相容活动子集合。

4用贪心算法解决活动安排的问题4.1贪心算法思路活动安排运用贪心算法的思路为,尽可能多的使更多的事件得到资源的安排。

按这种方法选择相容活动为未安排活动留下尽可能多的时间。

也就是说,该算法的贪心选择的意义是使剩余的可安排时间段极大化,以便安排尽可能多的相容活动。

实现方法是在满足相容的条件下,使结束时间靠前的活动得到资源,这样就为后续时间留下更多的安排时间,以使更多的活动得到安排。

的活动,而空白长条表示的活动是当前正在检查相容性的活动。

图1贪心算法的计算过程图i的开始时间Si小于最近选择的活动j的结束时间fi,则不选择活动贪心算法并不总能求得问题的整体最优解。

但对于活动安排问题,贪心算法却总能求得的整体最优解,即它最终所确定的相容活动集合A的规模最大。

这个结论可以用数学归纳法证明。

4.3 算法结果图2 运行结果4.4算法分析:贪心算法的效率极高,当输入的活动已按结束时间的非减序排列,算法只需O(n)的时间安排n个活动,使最多的活动能相容地使用公共资源。

如果所给出的活动未按非减序排列,可以对队列进行递减排序,最简只要用O(nlogn)的时间。

可以看出,在解决一个活动安排的问题是,只需要两个步骤。

一、对活动队列进行排序,二、用贪心算法对队列进行安排。

运用贪心算法只要很少的时间便能实现地问题的解决。

贪心算法 活动安排问题

贪心算法 活动安排问题

活动安排问题,对每项活动的按照结束时间非减序排列。

然后选第一个。

按照第一个的结束时间来看接下去怎么选,以此类推。

贪心选择性质的证明:
1.活动安排问题的一个最优解是以贪心选择开始。

即最优解包含第一个活动(叫做活动1)。

证明:假设有一个最优解叫做A。

它的活动也是以结束时间的非减序进行排列。

假设A中第一个活动叫做K。

如果K是我们的活动1,则A就是以活动1开始的。

如果K不是活动1.则把K从A中去掉,并加上活动1,而且活动1是相容的是因为活动1 的
结束时间最早。

所以证明了活动安排问题的一个最优解是以贪心选择开始。

最优子结构的证明:
把起始时间大于活动1的结束时间的活动去掉,A也可以把K去掉,这样子有一个递推的关系就是(总活动中)接下去那个与活动1相容的解必然可以相容在最优解(A-K)里面。

(因它又可以化为一个贪心选择的开始)所以每一步做出的贪心选择将使得原问题化为规模变小的相似的子问题。

贪心算法解决活动安排问题报告

贪心算法解决活动安排问题报告

1.引言:贪心法是一种改进了的分级处理方法。

用贪心法设计算法的特点是一步一步地进行,每一步上都要保证能获得局部最优解。

每一步只考虑一个数据,它的选取满足局部优化条件。

若下一个数据与部分最优解连在一起不再是可行解时,就不把该数据添加到部分解中,直到把所有数据枚举完,或者不能再添加为止。

这种能够得到某种度量意义下的最优解的分级处理方法称为贪心法。

贪心算法总是做出在当前看来是最优的选择,也就是说贪心算法并不是从整体上加以考虑,它所做出的选择只是在某种意义上的局部最优解,而许多问题自身的特性决定了该题运用贪心算法可以得到最优解或较优解。

2.贪心算法的基本思想及存在问题贪心法的基本思想:从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。

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

1.建立数学模型来描述问题。

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

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

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

3.活动安排问题:3.1 贪心算法解决活动安排问题学校举办活动的安排问题是用贪心算法有效求解的一个很好例子。

活动安排问题要求安排一系列争用某一公共资源的活动。

用贪心算法可使尽可能多的活动能兼容的使用公共资源。

设有n个活动的集合{0,1,2,…,n-1},其中每个活动都要求使用同一资源,如会场等,而在同一时间内只有一个活动能使用这一资源。

每个活动i都有一个要求使用该资源的起始时间starti和一个结束时间endi,且starti<endi。

如选择了活动i,则它在半开时间区间[starti,endi)内占用资源。

若区间[starti,endi)与区间[startj,endj)不相交,称活动i与活动j是相容的。

也就是说,当start j≥endi或starti≥endj时,活动i与活动j相容。

活动安排问题就是在所给的活动集合中选出最大的相容子活动集合。

C++贪心算法实现活动安排问题(实例代码)

C++贪心算法实现活动安排问题(实例代码)

C++贪⼼算法实现活动安排问题(实例代码)贪⼼算法贪⼼算法(⼜称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。

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

贪⼼算法不是对所有问题都能得到整体最优解,关键是贪⼼策略的选择,选择的贪⼼策略必须具备⽆后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。

具体代码如下所⽰:#include <cstdio>#include <iostream>#include <ctime>#include <windows.h>#include <algorithm>#include <fstream>using namespace std;struct activity{int no;int start;int finish;};bool cmp(const activity &x, const activity &y){return x.finish<y.finish;//从⼩到⼤排<,若要从⼤到⼩排则>}int greedySelector(int m,int solution[],struct activity activity[]){int number = 1;solution[0] = 1;int i,j = 0,counter = 1;for(i = 1;i < m ;i++){if(activity[i].start >=activity[j].finish){solution[i] = 1;j = i;counter++;}elsesolution[i] = 0;}cout << "The amount of activities is:"<<counter<<endl;cout << "The solution is:";for(i = 0 ;i < m ;i++){if (solution[i] == 1){cout << activity[i].no <<" ";}}return counter;}int main(void){LARGE_INTEGER nFreq;LARGE_INTEGER nBeginTime;LARGE_INTEGER nEndTime;ofstream fout;srand((unsigned int)time(NULL));int m,i,j,t;double cost;cout << "Please enter the number of times you want to run the program:";cin >> t;fout.open("activity.txt",ios::app);if(!fout){cerr<<"Can not open file 'activity.txt' "<<endl;return -1;}fout.setf(ios_base::fixed,ios_base::floatfield); //防⽌输出的数字使⽤科学计数法for (j = 0;j < t;j++){cout << "——————————————————The "<< j + 1 << "th test —————————————————"<<endl;m = 1 + rand()%100000;fout<<m<<",";int solution[m];activity activity[m];for( i = 0;i < m;i++){activity[i].no = i+1;activity[i].start = 1 + rand()%1000;while(1){activity[i].finish = 1 + rand()%10000;if(activity[i].finish > activity[i].start) break;}}QueryPerformanceFrequency(&nFreq);QueryPerformanceCounter(&nBeginTime);sort(activity,activity+m,cmp);greedySelector(m,solution,activity);QueryPerformanceCounter(&nEndTime);cost=(double)(nEndTime.QuadPart - nBeginTime.QuadPart) / (double)nFreq.QuadPart;fout << cost << endl;cout << "\nThe running time is:" << cost << " s" << endl;}fout.close();cout << endl << endl;cout << "Success!" << endl;return 0;}总结以上所述是⼩编给⼤家介绍的C++贪⼼算法实现活动安排问题,希望对⼤家有所帮助,如果⼤家有任何疑问请给我留⾔,⼩编会及时回复⼤家的。

贪心算法之会场安排问题

贪心算法之会场安排问题

贪⼼算法之会场安排问题【问题描述】假设要在⾜够多的会场⾥安排⼀批活动,并希望使⽤尽可能少的会场。

(这个问题实际上是著名的图着⾊问题。

若将每⼀个活动作为图的⼀个顶点,不相容活动间⽤边相连。

使相邻顶点有不同颜⾊的最⼩着⾊数,相应于要找的最⼩会场数。

)【数据输⼊】由⽂件input.txt给出输⼊数据,第⼀⾏⼜⼀个正整数K,表⽰有K个待安排的活动。

接下来有K⾏数据,每⾏有两个正整数,分别表⽰K个待安排的活动的开始时间和结束时间。

【结束输出】输出最少会场数。

input.txt output.txt5 31 2312 2825 3527 8036 50来吧,帮你解决介个问题。

思路:按照俺的思路啊~遍历所有的活动时间,设⼀个int sum代表会场的个数,如果时间可叠加到前⾯已有活动的会场的,把活动加到已有会场的数组中;如不可叠加,则新加会场重新加⼀个数组把这个新会场加⼊到新数组中然后sum+1。

遍历到最后 sum则就是需要最少的会场的个数·····下次再来。

我回来了,上⾯的思路我尝试了,没试出来。

就换了⼀种思路,就是做标记,已经加⼊的会场标记为1 否则为0 就OK了代码下次贴上#include <stdio.h>#define LEN 6int sum=0;int mark[LEN];void squarePlan(int s[],int f[]){int k=1,j;int flag=1;mark[0]=mark[1]=1;while(flag==1){mark[k]=1;for(int m=k+1;m<=LEN;m++){if(mark[m]==0&&s[m]>=f[k]){mark[m]=1;k=m;}}sum++;for(j=2;j<LEN;j++){if(mark[j]==0){k=j;break;}}flag=0;for(int i=1;i<LEN;i++){if(mark[i]==0&&i!=j){flag=1;break;}}}}int main(){ int s[LEN],f[LEN];int n;FILE *fp_in,*fp_out;fp_in=fopen("input.txt","r");//打开⼀个输⼊流,读取input.txt⽂件fp_out=fopen("output.txt","w");//打开⼀个输出流,写output.txt⽂件if(fp_in==NULL){printf("open in file failed\n");return 0;}if(fp_out==NULL){printf("open out file failed\n");return 0;}fscanf(fp_in,"%d",&n);s[0]=0;f[0]=0;for(int i=1;i<=n;i++){fscanf(fp_in,"%d",&s[i]);//x坐标在此题中⽆⽤,⽽y坐标在x坐标之后写⼊。

贪心算法经典例题

贪心算法经典例题

贪心算法经典例题贪心算法是一种求解最优问题的算法思想,其核心理念是每一步都选择当前最优的策略,从而达到全局最优解。

贪心算法可以应用于许多经典问题,下面将介绍几个常见的贪心算法经典例题及相关参考内容。

1. 会议室安排问题题目描述:给定一组会议的开始时间和结束时间,求解如何安排会议,使得尽可能多的会议可以在同一时间段内进行。

解题思路:贪心算法可以通过每次选择结束时间最早的会议来求解。

首先将会议按照结束时间排序,选择第一个会议作为首先安排的会议,然后依次选择后续结束时间不冲突的会议进行安排。

相关参考内容:- 《算法导论》第16章:贪心算法(ISBN: 9787115265955)- 《数据结构与算法分析》第13章:贪心算法(ISBN: 9787302483626)2. 零钱兑换问题题目描述:给定一定面额的硬币,求解如何用最少的硬币数量兑换指定金额的零钱。

解题思路:贪心算法可以通过每次选择面额最大且不超过目标金额的硬币来求解。

从面额最大的硬币开始,尽可能多地选择当前面额的硬币,并减去已经选择的硬币金额,直到金额为0。

相关参考内容:- 《算法导论》第16章:贪心算法(ISBN: 9787115265955)- 《算法4》第1章:基础(ISBN: 9787302444627)3. 区间调度问题题目描述:给定一组区间,求解如何选择尽可能多的不重叠区间。

解题思路:贪心算法可以通过每次选择结束时间最早的区间来求解。

首先将区间按照结束时间排序,选择第一个区间作为首先选择的区间,然后依次选择后续结束时间不与已经选择的区间重叠的区间进行选择。

相关参考内容:- 《算法导论》第16章:贪心算法(ISBN: 9787115265955)- 《数据结构与算法分析》第13章:贪心算法(ISBN: 9787302483626)4. 分糖果问题题目描述:给定一组孩子和一组糖果,求解如何分配糖果,使得最多的孩子能够得到满足。

解题思路:贪心算法可以通过每次选择糖果最小且能满足当前孩子的糖果来求解。

5.5主题活动:贪心算法

5.5主题活动:贪心算法
请说出你的想法
二 背包问题
装了音响,价值为3000元。但是价值不是最高的,如果是装笔 记本电脑和吉他,总价 值将为3500元。
在这里,贪心策略显然不能获得最优解,但是非常接近。
贪心算法
有时候,只需要找到一个能够大致解决问题的算法 ,此时贪心算法正好可以派上用场,因 为它们实现起来 很容易,得到的结果又与正确结果相当接近。
评一评
请根据本次动手实践情况,在表5-3中相应的位置涂“☆”。 (“非常好”涂☆☆☆☆ ☆,“好”涂☆☆☆,“还需努力”涂☆)
评价内容 理解贪心算法的含义
自评 ☆☆☆☆☆
能用贪心算法解决教室调度问题 ☆☆☆☆☆
能用贪心算法解决背包问题
☆☆☆☆☆
能说出贪心算法的优缺点
☆☆☆☆☆
互评
教师评
☆☆☆☆☆ ☆☆☆☆☆
请根据图思考具体做法。
一 教室调度问题
具体做法: 步骤1:选出结束最早的课,它就是要在这间教室上的第一堂课。 步骤2:选择第一堂课结束后才开始的课。同样,要选择结束得最早的课,这 将是要 在这间教室上的第二堂课。 步骤3:重复步骤1 和步骤2。 美术课结束得最早,为10:00,因此它就是第一堂课。接下来的课必须在10:00 后开 始,且结束得最早。英语课不行,因为它的时间与美术课冲突,数学课满 足条件。最后计算机课与数学课的时间是冲突的,音乐课可以。具体见表
一 教室调度问题
课程 美术 英语 数学 计算机 音乐
开始时间 9:00 9:30 10:00 10:30 11:00
结束时间 10:00 10:30 11:00 11:30 12:00
备注 √ X √ × √
因此根据表格,我们可以在这间教室上如下三堂课。
二 背包问题

贪心算法经典问题:活动安排,背包问题,最优装载,单源最短路径 Dijiksra,找零钱问题,多机调度

贪心算法经典问题:活动安排,背包问题,最优装载,单源最短路径 Dijiksra,找零钱问题,多机调度
{if (s[i]>=f[j]) { a[i]=true;j=i;count++;}
else a[i]=false;
}
return count;
}
背包问题
void Knapsack(int n,float M,float v[],float w[],float x[])
{Sort(n,v,w);//以每种物品单位重量的价值Vi/Wi从大到小排序
for(int i= 1;i<=n; i++)
{dist[i]=c[v][i]; s[i]=false;
if(dist[i]==maxint) prev[i]=0;
else prev[i]=v;
}
dist[v]=0 ; s[v]=true;
for(int i=1;i<n;i++)
{int temp = maxint, u = v;
if(newdist<dist[j]) {dist[j]= newdist;prev[j]=u; }
}
}//ENDFOR
}//END
找零钱问题
#define NUM4
void main()
{int m[NUM]={25,10,5,1};
int n;//假设n=99
cin>>n;
cout<<n<<"的找钱方案为:";
int max(int t[],int num);
int min(int t[],int m);
int set_work2(int t[],int n);
static int time[N]={2,8,18,32,50,72,98,128,182,200},s[M]={0,0,0};

贪心算法适用于哪些问题场景

贪心算法适用于哪些问题场景

贪心算法适用于哪些问题场景贪心算法是一种在求解问题时总是做出在当前看来是最好选择的算法。

虽然它不一定能得到全局最优解,但在许多特定的问题场景中,却能高效地给出一个较为满意的结果。

以下就来探讨一下贪心算法适用于哪些问题场景。

首先,贪心算法常用于活动安排问题。

假设有一系列活动,每个活动都有开始时间和结束时间。

我们需要在有限的时间内选择尽可能多的活动来参加。

此时,贪心算法的策略可以是每次都选择结束时间最早的活动。

因为这样能为后续可能的活动留出更多的时间,从而有可能安排更多的活动。

例如,有活动 A(开始时间 8:00,结束时间10:00)、B(开始时间 9:00,结束时间 11:00)、C(开始时间 10:30,结束时间 12:00)。

按照贪心算法,先选择 A 活动,然后由于 B 活动与 A 活动时间有冲突,不能选择,接着可以选择 C 活动。

这种情况下,通过贪心选择,能够安排两个活动。

其次,在找零钱问题中,贪心算法也能发挥作用。

比如,当我们需要用最少的硬币找给顾客零钱时,假设我们有 1 元、5 角、1 角的硬币,要找给顾客 17 元。

贪心算法会先尽量选择面值大的硬币,即先选择 1个 1 元硬币,然后选择 1 个 5 角硬币,再选择 2 个 1 角硬币,这样就能用最少的硬币数量找零。

再者,贪心算法在背包问题的某些变种中适用。

比如,在部分背包问题中,物品可以分割,每个物品都有一定的价值和重量。

我们要在背包容量有限的情况下,装入物品使得总价值最大。

此时,贪心算法可以按照物品的单位重量价值(价值/重量)从大到小的顺序来选择装入背包的物品。

例如,有物品 A(价值 100,重量 20)、物品 B(价值 60,重量 10)、物品 C(价值 80,重量 15),背包容量为 25。

按照贪心算法,先计算单位重量价值,A 为 5,B 为 6,C 为 533。

所以先选择 B 物品全部装入,然后选择 C 物品部分装入(10 重量),这样就能使背包内物品的总价值最大。

贪心算法-会场安排问题

贪心算法-会场安排问题

贪⼼算法-会场安排问题问题描述:假设要在⾜够多的会场⾥安排⼀批活动,并希望使⽤尽可能少的会场。

设计⼀个有效的贪⼼算法进⾏安排。

(这个问题实际上是著名的图着⾊问题。

若将每个活动作为图的⼀个顶点,不相容活动间⽤边相连。

使⽤相邻顶点着有不同颜⾊的最⼩着⾊数,相应于要找的最⼩会场数)。

[之所以想记录这个问题,就在于括号内的描述。

看完题⽬的描述,我⼼想:图着⾊问题不是有⼀个四⾊定理。

换⽽⾔之,即任何活动,只要四个会场就够了。

⽽这显然不符合常理。

后来发现,问题在于四⾊定理只适⽤于地图,在地图上最多四个国家相互接壤。

⽽活动显然不满⾜这个条件]算法描述:算法实现:#include<stdio.h>#include<stdlib.h>void makemap(int **map,int *early,int *late,int n){for(int i=0;i<n;i++)//当前被判断活动for(int j=i+1;j<n;j++)//其余活动{if((early[i]>=early[j]&&early[i]<=late[j])||(late[i]>=early[j]&&late[i]<=late[j])){//判断当前活动与其余活动是否交叉map[i][j]=map[j][i]=1;//交叉的话在图上做标记map[i][i]++;//记录与当前活动交叉活动的数⽬map[j][j]++;}}}//标记交叉活动void sortpoint(int **map,int *node,int low,int high){int i,j,temp,t,x;if(low<high){t=rand()%(high-low+1)+low;temp=node[t];node[t]=node[low];node[low]=temp;i=low;j=high;x=node[i];do{while(i<j && map[node[j]][node[j]]>=map[x][x]) j--;if(i<j) {node[i]=node[j];i++;}while(i<j && map[node[i]][node[i]]<map[x][x]) i++;if(i<j) {node[j]=node[i];j--;}}while(i!=j);node[i]=x;sortpoint(map,node,low,i-1);sortpoint(map,node,i+1,high);}}//依照活动与其他活动交叉的数⽬对活动进⾏随机快速排序//形成递增序列void colorit(int **map,int *node,int n){int *color;color=(int *)malloc((sizeof(int))*n);for(int i=0;i<n;i++)color[i]=0;color[node[n-1]]=0;for(int i=n-2;i>=0;i--){int elem[5]={0,0,0,0,0};for(int j=i+1;j<n;j++)if(map[i][j])elem[color[j]]=1;//根据图五⾊原理//设置数组标记与当前活动交叉且已分配会场的活动的举办会场for(int j=0;j<5;j++)if(elem[j]==0){color[i]=j;break;}//根据标记会场数组分配当前活动举办会场}int count=0;for(int i=0;i<n;i++)if(color[i]>count)count=color[i];count++;printf("%d",count);//统计开设会场的数⽬(结果)}//为每个活动分配会场int main(){int n;scanf("%d",&n);//活动数⽬nint **map;map=(int **)malloc((sizeof(int *))*n); for(int i=0;i<n;i++)map[i]=(int *)malloc((sizeof(int))*n); //⽤于记录活动间的交叉情况int *early;int *late;early=(int *)malloc((sizeof(int))*n);late=(int *)malloc((sizeof(int))*n);//⽤于记录活动的开始时间和结束时间for(int i=0;i<n;i++){scanf("%d %d",&early[i],&late[i]);for(int j=0;j<n;j++)map[i][j]=0;}makemap(map,early,late,n);int *node;node=(int *)malloc((sizeof(int))*n); for(int i=0;i<n;i++)node[i]=i;sortpoint(map,node,0,n-1);colorit(map,node,n);return0;}View Code。

贪心算法-会场安排

贪心算法-会场安排

贪⼼算法-会场安排(1)问题描述:假设要在⾜够多的会场⾥安排⼀批活动,并希望使⽤尽可能少的会场。

前提每个活动都有开始和结束时间,⼀个会场中多个活动不能交叉进⾏,只能按次序进⾏,设计⼀个有效的贪⼼算法进⾏安排。

(2)算法设计:对于给定的 activities 个带安排的活动,计算使⽤最少会场的时间表;(3)数据输⼊:第⼀⾏输⼊待安排的活动数量 activities。

接下来 activities ⾏中,每⼀⾏有 2 个整数,分别表⽰ activities 个待安排的活动的开始和结束时间;(4)思想:记录每个活动的开始和结束时间,按照升序排列,遍历活动开始【START】和结束【FINISHED】标识,遇到 START,加 1,遇到 FINISHED,减 1,然后遍历活动标识数组,找出最⼤值即为最少会场数量;(5)代码展⽰:public class MeetingArrange {/*** 会场开始结束标识*/private static final String START = "start";private static final String FINISHED = "finished";/*** 会场安排的活动数量*/private static Integer activities = 0;/*** 记录当前最少的会场个数*/private static Integer minMettings = 0;/*** 记录当前会场的数量*/private static Integer[] nowMettingCount;/*** 活动安排开始结束时间数组*/private static Integer[] startAndFinishedTime;/*** 活动安排开始结束标识*/private static String[] flag;/*** 初始化数据*/private static void initData() {Scanner input = new Scanner(System.in);System.out.println("请输⼊安排的活动数量:");activities = input.nextInt();System.out.println("请输⼊每个活动开始和结束时间:");startAndFinishedTime = new Integer[activities * 2];flag = new String[activities * 2];nowMettingCount = new Integer[flag.length];for (int i = 0; i < activities * 2; i = i + 2) {startAndFinishedTime[i] = input.nextInt(); // 活动开始时间startAndFinishedTime[i + 1] = input.nextInt(); // 活动结束时间flag[i] = START; // 活动开始标识flag[i + 1] = FINISHED; // 活动结束标识nowMettingCount[i] = 0; // 初始化当前会场数量为 0}}/*** 活动起始、结束时间数组升序排列*/private static void sortAsc() {Integer temp;Integer change = 1;String str;for (int i = 0; i < startAndFinishedTime.length - 1 && change == 1; i++) {change = 0;for (int j = 0; j < startAndFinishedTime.length - i - 1; j++) {if (startAndFinishedTime[j] > startAndFinishedTime[j + 1]) {// 活动开始和结束时间交换temp = startAndFinishedTime[j];startAndFinishedTime[j] = startAndFinishedTime[j + 1];startAndFinishedTime[j + 1] = temp;// 活动开始和结束标识交换str = flag[j];flag[j] = flag[j + 1];flag[j + 1] = str;change = 1;}}}}/*** 统计最少的会场数量* 思想:遇到 START,当前会场数量加 1,遇到 FINISHED,当前会场数量减 1;然后遍历当前会场数量数组,取最⼤值即为最少会场数*/private static Integer countMinMettings() {for (int i = 0; i < flag.length; i++) {if (flag[i].equals(START)) {minMettings++;} else {minMettings--;}nowMettingCount[i] = minMettings;}// 找出最少的会场数量return Stream.of(nowMettingCount).max(paringInt(o -> o)).get();}public static void main(String[] args) {// 初始化数据initData();// 升序sortAsc();// Stream.of(startAndFinishedTime).forEach(element -> System.out.print(element + " "));// 统计最少的会场数量Integer min = countMinMettings();System.out.println("最少的会场数量为:" + min);}}(6)输⼊输出:请输⼊安排的活动数量:5请输⼊每个活动开始和结束时间:1 2312 2825 3527 8036 50最少的会场数量为:3(7)总结:会场安排完全阐释了贪⼼算法的核⼼思想,统计出多个局部最优解,在此局部最优解的集合中,选择⼀个整体的最优解; 。

贪心算法----活动时间安排

贪心算法----活动时间安排

实验二:贪心算法【实验目的】深入理解贪心法的算法思想,应用贪心算法解决实际的算法问题。

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

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

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

【程序代码】# include <>void input(int a[ ][3]); //输入活动时间void sort (int a[ ][3]); //排序void output1 (int a[ ][3]); //排序的结果输出int greed (int a[ ][3], int arr[][50][3], int m); //判断记录被选中的活动时间void output2 (int a[][50][3], int y,int m); //输出最大的的活动时间int yi=0;int n;int main (){int array[50][3];int arr[50][50][3]={0};int z, y, m, b[12]={0};printf ("活动总数量n(n<50)!!! \n\n");scanf ("%d", &n);input (array);sort (array);printf ("\n");output1 (array);printf ("\n");for (m=0; m<n; m++)b[m] = greed (array, arr, m);y = 0;for (m=0; m<n; m++)if (y < b[m]){y = b[m];z = m;}printf ("安排活动时间的最大相容子集:\n");output2 (arr, y,z);return 0;}void input(int a[ ][3]){int i, j;for (i=0; i<n; i++){a[i][0]=i+1;printf ("请输入第%d个活动的开始时间和结束时间:", i+1);for(j=1; j<3; j++)scanf ("%d", &a[i][j]);}}void sort (int a[ ][3]){int i, j, k, t;for (i=0; i<n-1; i++)for (j=0; j<n-1-i; j++)for (k=0; k<3; k++)if (a[j][2] > a[j+1][2]){t = a[j][k];a[j][k] = a[j+1][k];a[j+1][k] = t;}}void output1 (int a[ ][3]){int i, j;printf ("按结束时间的升序排列如下:\n");for (i=0; i<n; i++){printf ("原来序号%d的开始时间和结束时间:", a[i][0]);for (j=1; j<3; j++)printf (" %d", a[i][j]);printf ("\n");}}int greed (int a[ ][3], int arr[][50][3], int m){int i, j, k, y=1;k = a[m][2];//for (i=0; i<3; i++)arr[yi][0][i] = a[m][i];//for (i=m; i<n; i++){if (k <= a[i][1]){k = a[i][2];for (j=0; j<3; j++)arr[yi][y][j] = a[i][j];y++;}}yi++;return y;}void output2 (int a[][50][3], int y,int m){int i, j;for (i=0; i<y; i++){printf ("选中了原来序号为第%d活动,他的开始结束时间分别为:", a[m][i][0]);for (j=1; j<3; j++){printf ("%d ", a[m][i][j] );}printf ("\n");}}法二#include <>#define active_num 11 //活动数#define true 1 //记录被选的活动#define false 0 //未被选择的活动int greedySelector(int s[],int f[],int b[])// 算法{b[0] = true;int j = 0;int i = 1;int count = 1;for(i = 1;i <=active_num; i++ ){if(s[i] > f[j]){b[i] = true;j = i;count++;}elseb[i] = false;}printf("active number is %d\n",count); for(i=0;i<active_num;i++){if(b[i] == 1)printf("%d ",i+1);}return0;}int main(){int i;int start_time[active_num];int finish_time[active_num];int boolean[active_num];printf("please input the start time\n");for(i = 0; i < active_num; i++)scanf("%d",&start_time[i]);printf("please input the finish time\n");for(i = 0; i < active_num; i++)scanf("%d",&finish_time[i]);greedySelector(start_time ,finish_time ,boolean);return0;}。

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

活动安排问题,对每项活动的按照结束时间非减序排列。

然后选第一个。

按照第一个的结束时间来看接下去怎么选,以此类推。

•第一步二
-选择活动1作为第一个被选中的活动,并将活动1的结束时间作
为判断下一个活动是否被选中的依据;
•第二步’
-判断活动2与活龙T是否相容
-即引2]是否大于或等于耳
];
1
结果土不相容,活动2没有被选中,活动1的结束时间仍作为判断下一个活动是否被选中的依据
•第三步M
-判断活动3与活或T是否相容•即引3]是否大于或等于耳1]:
结果士不相容,活动礙有被选中,活动1的结束时间仍作为判断下一个活动是否被选中的依据
•第四步&
-判斷活动4与活动T是否相容-即H4]是否大于或等于di]:
结果:相容,活动4袱选中,活动4的结束时间将作为判断下一个活动是否被选中的依据
10
贪心选择性质的证明:
1.活动安排问题的一个最优解是以贪心选择开始。

即最优解包含第一个活动(叫做活动1 )。

证明:假设有一个最优解叫做A。

它的活动也是以结束时间的非减序进行排列。

假设A中第一个活动叫做K。

如果K是我们的活动1,则A就是以活动1开始的。

如果K不是活动1•则把K从A中去掉,并加上活动1,而且活动1是相容的是因为活动1的结束时间最早。

所以证明了活动安排问题的一个最优解是以贪心选择开始。

最优子结构的证明:
把起始时间大于活动1的结束时间的活动去掉,A也可以把K去掉,这样子有一个递推的关系就是(总活动中)接下去那个与活动1相容的解必然可以相容在最优解(A-K)里面。

(因它又可以化为一个贪心选择的开始)所以每一步做出的贪心选择将使得原问题化为规模变小的相似的子问题。

相关文档
最新文档