0021算法笔记——【贪心算法】贪心算法与精彩活动安排问题

0021算法笔记——【贪心算法】贪心算法与精彩活动安排问题
0021算法笔记——【贪心算法】贪心算法与精彩活动安排问题

0021算法笔记——【贪心算法】贪心算法与活动安排问题

1、贪心算法

(1)原理:在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,但对围相当广泛的许多问题他能产生整体最优解或者是整体最优解的近似解。

(2)特性:贪心算法采用自顶向下,以迭代的方法做出相继的贪心选择,每做一次贪心选择就将所求问题简化为一个规模更小的子问题,通过每一步贪心选择,可得到问题的一个最优解,虽然每一步上都要保证能获得局部最优解,但由此产生的全局解有时不一定是最优的,所以贪婪法不要回溯。能够用贪心算法求解的问题一般具有两个重要特性:贪心选择性质和最优子结构性质。

1)贪心选择性质

所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这是贪心算法可行的第一个基本要素。贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。

对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。证明的大致过程为:首先考察问题的一个整体最优解,并证明可修改这个最优解,使其以贪心选择开始。做了贪心选择后,原问题简化为规模更小的类似子问题。然后用数学归纳法证明通过每一步做贪心选择,最终可得到问题的整体最优解。其中,证明贪心选择后的问题简化为规模更小的类似子问题的关键在于利用该问题的最优子结构性质。

2)最优子结构性质

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

(3)贪心算法与动态规划算法的差异:

动态规划和贪心算法都是一种递推算法,均有最优子结构性质,通过局部最优解来推导全局最优解。两者之间的区别在于:贪心算法中作出的每步贪心决策都无法改变,因为贪心策略是由上一步的最优解推导下一步的最优解,而上一部之前的最优解则不作保留,贪心算法每一步的最优解一定包含上一步的最优解。动态规划算法中全局最优解中一定包含某个局部最优解,但不一定包含前一个局部最优解,因此需要记录之前的所有最优解。

(4)基本思路:

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

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

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

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

2、活动安排问题

活动安排问题就是要在所给的活动集合中选出最大的相容活动子集合,是可以用贪心算法有效求解的很好例子。该问题要求高效地安排一系列争用某一公共资源的活动。贪心算法提供了一个简单、漂亮的方法使得尽可能多的活动能兼容地使用公共资源。

问题描述:

设有n个活动的集合E={1,2,…,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi,且si

求解思路:

将活动按照结束时间进行从小到大排序。然后用i代表第i 个活动,s[i]代表第i个活动开始时间,f[i]代表第i个活动的结束

时间。按照从小到大排序,挑选出结束时间尽量早的活动,并且满足后一个活动的起始时间晚于前一个活动的结束时间,全部找出这些活动就是最大的相容活动子集合。事实上系统一次检查活动i是否与当前已选择的所有活动相容。若相容活动i加入已选择活动的集合中,否则,不选择活动i,而继续下一活动与集合A中活动的相容性。若活动i与之相容,则i成为最近加入集合A的活动,并取代活动j的位置。

下面给出求解活动安排问题的贪心算法,各活动的起始时间和结束时间存储于数组s和f中,且按结束时间的非减序排列。如果所给的活动未按此序排列,可以用O(nlogn)的时间重排。具体代码如下:

[cpp]view plain copy

1.//4d1 活动安排问题贪心算法

2.#include "stdafx.h"

3.#include

https://www.360docs.net/doc/ed17402931.html,ing namespace std;

5.

6.template

7.void GreedySelector(int n, Type s[], Type f[], bool A[]);

8.

9.const int N = 11;

10.

11.int main()

12.{

13.//下标从1开始,存储活动开始时间

14.int s[] = {0,1,3,0,5,3,5,6,8,8,2,12};

15.

16.//下标从1开始,存储活动结束时间

17.int f[] = {0,4,5,6,7,8,9,10,11,12,13,14};

18.

19.bool A[N+1];

20.

21.cout<<"各活动的开始时间,结束时间分别为:"<

22.for(int i=1;i<=N;i++)

23.{

24.cout<<"["<

25.}

26.GreedySelector(N,s,f,A);

27.cout<<"最大相容活动子集为:"<

28.for(int i=1;i<=N;i++)

29.{

30.if(A[i]){

31.cout<<"["<

32.}

33.}

34.

35.return0;

36.}

37.

38.template

39.void GreedySelector(int n, Type s[], Type f[], bool A[])

40.{

41.A[1]=true;

42.int j=1;//记录最近一次加入A中的活动

43.

44.for(int i=2;i<=n;i++)//依次检查活动i是否与当前已选择的活动相容

45.{

46.if(s[i]>=f[j])

47.{

48.A[i]=true;

49.j=i;

50.}

51.else

52.{

53.A[i]=false;

54.}

55.}

56.}

由于输入的活动以其完成时间的非减序排列,所以算法greedySelector每次总是选择具有最早完成时间的相容活动加入集合A 中。直观上,按这种方法选择相容活动为未安排活动留下尽可能多的时间。也

就是说,该算法的贪心选择的意义是使剩余的可安排时间段极大化,以便安排尽可能多的相容活动。算法greedySelector的效率极高。当输入的活动已按结束时间的非减序排列,算法只需O(n)的时间安排n个活动,使最多的活动能相容地使用公共资源。如果所给出的活动未按非减序排列,可以用O(nlogn)的时间重排。

例:设待安排的11个活动的开始时间和结束时间按结束时间的非减序排列如下:

算法greedySelector 的计算过程如下图所示。图中每行相应于算法的一次迭代。阴影长条表示的活动是已选入集合A的活动,而空白长条表示的活动是当前正在检查相容性的活动。

若被检查的活动i的开始时间Si小于最近选择的活动j的结束时间fi,则不选择活动i,否则选择活动i加入集合A中。贪心算法并不总能求得问题的整体最优解。但对于活动安排问题,贪心算法greedySelector却总能求得的整体最优解,即它最终所确定的相容活动集合A的规模最大。这个结论可以用数学归纳法证明。

证明如下:设E={0,1,2,…,n-1}为所给的活动集合。由于E中活动安排安结束时间的非减序排列,所以活动0具有最早完成时间。首先证明活动安排问题有一个最优解以贪心选择开始,即该最优解中包含活动0.设a是所给的活动安排问题的一个最优解,且a 中活动也按结束时间非减序排列,a中的第一个活动是活动k。如

k=0,则a就是一个以贪心选择开始的最优解。若k>0,则我们设b=a-{k}∪{0}。由于end[0] ≤end[k],且a中活动是互为相容的,故b中的活动也是互为相容的。又由于b中的活动个数与a中活动个数相

同,且a是最优的,故b也是最优的。也就是说b是一个以贪心选择活动0开始的最优活动安排。因此,证明了总存在一个以贪心选择开始的最优活动安排方案,也就是算法具有贪心选择性质。

程序运行结果如下:

贪心算法 会场安排问题 算法设计分析

贪心算法会场安排问题算法设计分析Description 假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。设计一个有效的算法进行安排。(这个问题实际上是著名的图着色问题。若将每一个活动作为图的一个顶点,不相容活动间用边相连。使相邻顶点着有不同颜色的最小着色数,相应于要找的最小会场数。) 编程任务: 对于给定的k个待安排的活动,编程计算使用最少会场的时间表。 Input 输入数据是由多组测试数据组成。每组测试数据输入的第一行有1 个正整数k,表示有k个待安排的活动。接下来的k行中,每行有2个正整数,分别表示k 个待安排的活动开始时间和结束时间。时间以0 点开始的分钟计。 Output 对应每组输入,输出的每行是计算出的最少会场数。 Sample Input 5 1 23 12 28 25 35 27 80 3 6 50

Sample Output 3 程序: #include int fnPartition(int a[], int low, int high) { int i,j; int x = a[low]; i = low; j = high; while(i =a[i]) i++; if(i -1) { n = 1; for(; i <=e; i++) if(a[i]>=b[s]) s++; else n++; } return n; } int main(void) { int n,i; while(1 == scanf("%d",&n)) { int *st = new int [n]; int *et = new int [n]; for (i = 0; i

算法设计(eclipse编写贪心算法设计活动安排)

陕西师大计科院2009级《算法设计与分析》课程论文集 算法设计(贪心算法解决活动安排) 设计者:朱亚君 贪心算法的计算过程如下图所示。图中每行相应于算法的一次迭代。阴影长条表示的活动是已选入集合A的活动,而空白长条表示的活动是当前正在检查相容性的活动。 图1贪心算法的计算过程图 若被检查的活动i的开始时间Si小于最近选择的活动j的结束时间fi,则不选择活动i,否则选择活动i加入集合A中。 贪心算法并不总能求得问题的整体最优解。但对于活动安排问题,贪心算法却总能求得的整体最优解,即它最终所确定的相容活动集合A的规模最大。这个结论可以用数学归纳法证明。

运用贪心算法解决活动安排问题 附录: 贪心算法的实现具体程序如下: // 贪心算法实现代码 n为活动个数 s为活动开始起始时间队列 f 为活动结束队列 A为已选入集合 import java.util.Scanner; public class a { /** * @param args */ static void GreedySelector(int s[],int f[],boolean A[]) { //第一个活动为结束时间最早进入选入队列 int n=s.length; A[1]=true; int j=2; for(int i=2;i=f[j]) { A[i]=true; j=i; } else A[i]=false; } } static void paixu(int s[],int f[])//进行以结束时间的大小排序 { int n=s.length; int m; for(int i=0;if[j+1]) { m=f[j]; f[j]=f[j+1]; f[j+1]=m;//终止时间如果前一个大于后一个就交换位置

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

1.引言: 贪心法是一种改进了的分级处理方法。用贪心法设计算法的特点是一步一步地进行,每一步上都要保证能获得局部最优解。每一步只考虑一个数据,它的选取满足局部优化条件。若下一个数据与部分最优解连在一起不再是可行解时,就不把该数据添加到部分解中,直到把所有数据枚举完,或者不能再添加为止。这种能够得到某种度量意义下的最优解的分级处理方法称为贪心法。 贪心算法总是做出在当前看来是最优的选择,也就是说贪心算法并不是从整体上加以考虑,它所做出的选择只是在某种意义上的局部最优解,而许多问题自身的特性决定了该题运用贪心算法可以得到最优解或较优解。 2.贪心算法的基本思想及存在问题 贪心法的基本思想: 从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到某算法中的某一步不能再继续前进时,算法停止。 1.建立数学模型来描述问题。 2.把求解的问题分成若干个子问题。 3.对每一子问题求解,得到子问题的局部最优解。 4.把子问题的解局部最优解合成原来解问题的一个解。 3.活动安排问题: 3.1 贪心算法解决活动安排问题 学校举办活动的安排问题是用贪心算法有效求解的一个很好例子。活动安排问题要求安排一系列争用某一公共资源的活动。用贪心算法可使尽可能多的活动能兼容的使用公共资源。设有n个活动的集合{0,1,2,…,n-1},其中每个活动都要求使用同一资源,如会场等,而在同一时间内只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源的起始时间starti和一个结束时间endi,且starti

0021算法笔记——【贪心算法】贪心算法与活动安排问题

0021算法笔记——【贪心算法】贪心算法与活动安排问题 1、贪心算法 (1)原理:在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题他能产生整体最优解或者是整体最优解的近似解。 (2)特性:贪心算法采用自顶向下,以迭代的方法做出相继的贪心选择,每做一次贪心选择就将所求问题简化为一个规模更小的子问题,通过每一步贪心选择,可得到问题的一个最优解,虽然每一步上都要保证能获得局部最优解,但由此产生的全局解有时不一定是最优的,所以贪婪法不要回溯。能够用贪心算法求解的问题一般具有两个重要特性:贪心选择性质和最优子结构性质。 1)贪心选择性质 所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局 部最优的选择,即贪心选择来达到。这是贪心算法可行的第一个基本要素。贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。 对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。证明的大致过程为:

首先考察问题的一个整体最优解,并证明可修改这个最优解,使其以贪心选择开始。做了贪心选择后,原问题简化为规模更小的类似子问题。然后用数学归纳法证明通过每一步做贪心选择,最终可得到问题的整体最优解。其中,证明贪心选择后的问题简化为规模更小的类似子问题的关键在于利用该问题的最优子结构性质。 2)最优子结构性质 当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。 (3)贪心算法与动态规划算法的差异: 动态规划和贪心算法都是一种递推算法,均有最优子结构性质,通过局部最优解来推导全局最优解。两者之间的区别在于:贪心算法中作出的每步贪心决策都无法改变,因为贪心策略是由上一步的最优解推导下一步的最优解,而上一部之前的最优解则不作保留,贪心算法每一步的最优解一定包含上一步的最优解。动态规划算法中全局最优解中一定包含某个局部最优解,但不一定包含前一个局部最优解,因此需要记录之前的所有最优解。 (4)基本思路: 1)建立数学模型来描述问题。 2)把求解的问题分成若干个子问题。 3)对每一子问题求解,得到子问题的局部最优解。 4)把子问题的解局部最优解合成原来解问题的一个解。 2、活动安排问题

贪心算法解活动安排实验报告

实验3 贪心算法解活动安排问题 一、实验要求 1.要求按贪心法求解问题; 2.要求读文本文件输入活动安排时间区间数据; 3.要求显示结果。 二、实验仪器和软件平台 仪器:带usb接口微机 软件平台:WIN-XP + VC++6.0 三、源程序 #include "stdafx.h" #include #include #include #define N 50 #define TURE 1 #define FALSE 0 int s[N];/*开始时间*/ int f[N];/*结束时间*/ int A[N];/*用A存储所有的*/ int Partition(int *b,int *a,int p,int r); void QuickSort(int *b,int *a,int p,int r); void GreedySelector(int n,int *s,int *f,int *A); int main() { int n=0,i; while(n<=0||n>50) { printf("\n"); printf("请输入活动的个数,n="); scanf("%d",&n); if(n<=0) printf("请输入大于零的数!"); else if(n>50) printf("请输入小于50的数!"); } printf("\n请分别输入开始时间s[i]和结束时间f[i]:\n\n"); for(i=1;i<=n;i++) { printf("s[%d]=",i,i); scanf("%d",&s[i]);

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

贪心算法解决活动安排问题 金潇 Use the greedy algorithm to solve the arrangement for activities Jinxiao 摘要:贪心算法在当前来看是最好的选择。是用利用启发式策略,在不从整体最优上加以考虑的情况下,来做出局部最优选择的一种算法。本文通过贪心算法的经典案例—活动安排问题入手,描述了贪心算法的基本思想和可能产生的问题,并简述该算法的好处和特点,最后给出几种经典的贪心算法。 关键字:贪心算法、局部最优选择 Abstract:A greedy algorithm is any algorithm that follows the problem solving heuristic of making the locally optimal choice at each stage with the hope of finding the global optimum. This article through the greedy algorithm of the classic case--activities problems, describes the greedy algorithm the basic ideas and possible problems, and briefly introduces the advantages and characteristics of the algorithm, and finally gives several classic the greedy algorithm. Keywords:greedy algorithm、the locally optimal choice 1.引言: 贪心法是一种改进了的分级处理方法。用贪心法设计算法的特点是一步一步地进行,每一步上都要保证能获得局部最优解。每一步只考虑一个数据,它的选取满足局部优化条件。若下一个数据与部分最优解连在一起不再是可行解时,就不把该数据添加到部分解中,直到把所有数据枚举完,或者不能再添加为止。这种能够得到某种度量意义下的最优解的分级处理方法称为贪心法。 其实,从"贪心"一词我们便可以看出,贪心算法总是做出在当前看来是最优的选择,也就是说贪心算法并不是从整体上加以考虑,它所做出的选择只是在某种意义上的局部最优解,而许多问题自身的特性决定了该题运用贪心算法可以得到最优解或较优解。许多可以用贪心算法求解的问题一般具有贪心选择性质和最优子结构,贪心选择性质是指所求问题的整体最优解包含着局部最优的选择,对于一个具体问题,关键是证明或验证每一步所作的贪心选择最终将导致问题的一个整体最优解。

贪 心 算 法

【贪心算法】思想 & 基本要素 & 贪心算法与局部最优 & 贪心算法与动态规划的区别 & 运用贪心算法求解问题 首先我们先代入问题来认识一下贪心算法涉及的问题 找钱问题 给顾客找钱,希望找零的钞票尽可能少,零钱种类和数量限定 找钱问题满足最优子结构 最快找零(贪心):为得到最小的找零次数,每次最大程度低减少零额活动安排问题 设个活动都需要使用某个教室,已知它们的起始时间和结束时间,求合理的安排使得举行的活动数量最多 贪心:使得每次安排后,教室的空闲时间最多 解决过程如下: 贪心算法求得的相容活动集是最大的 第一步:证明最优解中包含结束时间最早的活动 设相容集 A 是一个最优解,其结束最早的活动为 a,则 ( A - { a }) U { 1 } 也是一个最优解 第二步:证明去掉结束时间最早的活动后,得到的子问题仍是最优的:反证法 理解贪心算法 贪心算法总是做出当前最好的选择 贪心选择的依据是当前的状态,而不是问题的目标

贪心选择是不计后果的 贪心算法通常以自顶向下的方法简化子问题 贪心算法求解的问题具备以下性质 贪心选择性质:问题的最优解可以通过贪心选择实现 最优子结构性质:问题的最优解包含子问题的最优解 贪心选择性质的证明 证明问题的最优解可以由贪心选择开始 即第一步可贪心 证明贪心选择后得到的子问题满足最优子结构 即步步可贪心 背包问题 问题描述:给定 n 个物品和一个背包。物品 i 的重量为 Wi ,价值为 Vi ,背包的容量为 c ,问如何选择物品或物品的一部分,使得背包中物品的价值最大? 当 n = 3 ,c = 50 0-1背包问题:装入物品2、3,最大价值220 背包问题:装入物品1、2和2-3的物品3,最大价值240(贪心算法)贪心算法无法求解0-1背包问题,按贪心算法,0-1背包问题将装入物品1和2 贪心与局部最优 思考:为什么0-1背包可以用动态规划?而不能用贪心算法 贪心易陷入局部最优

贪心算法经典问题:活动安排,背包问题,最优装载,单源最短路径 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]];} //调整剩余空间 } 单源最短路径Dijiksra template 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;

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

中原工学院计算机学院 实验报告 实验项目名称实验二、最少活动会场安排问题课程名称算法设计与分析 学生姓名梁斐燕 学生学号201400824204 所在班级网络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; } } ㈡、函数调用及主函数设计 (可用函数的调用关系图说明) 主函数 快排选择活动

贪心算法的应用实例

贪心算法的应用实例 例2.排队问题 【题目描述】 在一个医院B 超室,有n个人要做不同身体部位的B超,已知每个人需要处理的时间为ti,(00,从而新的序列比原最优序列好,这与假设矛盾,故s1为最小时间,同理可证s2…sn依次最小。 例3.:数列极差问题 【题目描述】 在黑板上写了N个正整数做成的一个数列,进行如下操作:每一次擦去其中的两个数a 和b,然后在数列中加入一个数a×b+1,如此下去直至黑板上剩下一个数,在所有按这种操作方式最后得到的数中,最大的max,最小的为min,则该数列的极差定义为M=max-min。 编程任务:对于给定的数列,编程计算出极差M。 输入输出样例: 输入: 4 2 1 4 3 输出: 13 【算法分析】 当看到此题时,我们会发现求max与求min是两个相似的过程。若我们把求解max与min的过程分开,着重探讨求max的问题。 下面我们以求max为例来讨论此题用贪心策略求解的合理性。 讨论:假设经(N-3)次变换后得到3个数:a ,b , max'(max'≥a≥b),其中max'是(N-2)个数经(N-3)次f变换后所得的最大值,此时有两种求值方式,设其所求值分别为 z1,z2,则有:z1=(a×b+1)×max'+1,z2=(a×max'+1)×b+1所以z1-z2=max'-b≥0若经(N-2)次变换后所得的3个数为:m,a,

贪心法解决活动安排问题

运用贪心算法解决活动安排问题 李文治,陈平,谢华欣,韩月梅 (陕西师范大学计算机科学学院09级软件工程,西安,710062) 摘要:生活中经常可以遇到这样一些问题,需要对一些资源进行优化分配已达到资源利用率的最大化。如对会场会议的安排、对赛场比赛的安排、课程的安排、以及扩展到电脑中操作系统对不同进程资源的分配问题。使用贪心算法可以很快的解决此类安排问题。 关键词:活动安排安排;贪心算法; Using the greedy algorithm to solve the problem of activity arrangement Li Wenzhi, Chen Ping, Xie Huaxin, Han Y uemei ( Shaanxi Normal University computer science institute of software engineering, Xi'an, 710062) Abstract:life can often encounter such problems, the need for some resource optimized allocation has achieve the maximization of resource utilization. As for the meeting venue arrangement, the Games arrangement, the arrangement of the courses, as well as an extension to the computer operating system on the process of different resource allocation problems. The use of greedy algorithm can quickly solve such arrangements. Keywords:activity arrangement; greedy algorithm; 1引言 生活中经常可以遇到这样一些问题,需要对一些资源进行优化分配已达到资源利用率的最大化。如对会场会议的安排、对赛场比赛的安排、课程的安排、以及扩展到电脑中操作系统对不同进程资源的分配问题。而贪心算法目前是解决这种安排问题的比较好的解决方法之一。 2 贪心算法简介 贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题他能产生整体最优解或者是整体最优解的近似解。 3问题概述 设有n个活动的集合E={1,2,……,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi,且si

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

实验二:贪心算法 【实验目的】 深入理解贪心法的算法思想,应用贪心算法解决实际的算法问题。 【实验性质】 验证性实验。 【实验要求】 有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

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

HUBEI UNIVERSITY OF AUTOMOTIVE TECHNOLOGY 算法设计与分析 实验报告 实验项目实验二实验类别验证性学生姓名王龙学生学号7 完成日期2016-4-15 指导教师刘振章 实验成绩评阅日期 评阅教师刘振章

实验二:贪心算法 【实验目的】 深入理解贪心法的算法思想,应用贪心算法解决实际的算法问题。 【实验性质】 验证性实验。 【实验要求】 有n个活动的集合A={1,2,…,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。求解安排尽量多项活动在该场地进行,即求A的最大相容子集。 设待安排的11个活动的开始时间和结束时间按结束时间的升序排列如下: 将此表数据作为实现该算法的测试数据。 【算法思想及处理过程】

【程序代码】

printf ("\n"); for (m=0; m<11; m++) b[m] = greed (array, arr, m); y = 0; for (m=0; m<11; 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; printf ("请按提示操作!!! \n\n"); for (i=0; i<11; i++) { a[i][0]=i+1; printf ("请输入第%d个活动的开始时间和结束时间:", i+1);

贪心算法 会场安排问题

计算机算法设计与分析(第3版) 128页 算法实现题4-1 会场安排问题 问题描述:假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。设计一个有效的算法进行安排。(这个问题实际上是著名的图着色问题。若将每一个活动作为图的一个顶点,不相容活动间用边相连。使相邻顶点着有不同颜色的最小着色数,相应于要找的最小会场数。) 编程任务:对于给定的k 个待安排的活动,编程计算使用最少会场的时间表。Input 输入数据是由多组测试数据组成。每组测试数据输入的第一行有1 个正整数k,表示有k 个待安排的活动。接下来的k 行中,每行有2 个正整数,分别表示k 个待安排的活动开始时间和结束时间。时间以0 点开始的分钟计。Output 对应每组输入,输出的每行是计算出的最少会场数。 源代码: #include int fnPartition(int a[], int low, int high) { int i,j; int x = a[low]; i = low; j = high; while(i =a[i]) i++; if(i -1)

贪心算法详解

第16章贪心算法 理解贪心算法的概念 z z掌握贪心算法的基本要素 z理解贪心算法与动态规划算法的差异 z通过范例学习贪心算法设计策略

161 16.1 活动安排问题 z当一个问题具有最优子结构性质时,可用动态规划法求解,但有时用贪心算法求解会更加的简单有效。 z顾名思义,贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。当然,希望贪心算法得到的最终结果也是整体最优的。虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。单源最短路经问题,最小生成树问题等。在些情解。如单源最短路经问题,最小生成树问题等。在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。

161z 设有n个活动的集合E={1,2,…,n},其中每个活动都要求使16.1 活动安排问题用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源和个结束时间f 且s 如果选择了活动i 的起始时间s i 和一个结束时间f i ,且s i

16.1 活动安排问题 161 (用动态规划方法) z步骤1:分析最优解的结构特征 —构造子问题空间: S ij={ a k∈S: f i≤s k

贪心算法解活动安排实验报告

实验3 贪心算法解活动安排问题一、实验要求 1.要求按贪心法求解问题; 2.要求读文本文件输入活动安排时间区间数据; 3.要求显示结果。 二、实验仪器和软件平台 仪器:带usb接口微机 软件平台:WIN-XP + VC++6.0 三、源程序 #include "stdafx.h" #include #include #include #define N 50 #define TURE 1 #define FALSE 0 int s[N];/*开始时间*/ int f[N];/*结束时间*/ int A[N];/*用A存储所有的*/ int Partition(int *b,int *a,int p,int r); void QuickSort(int *b,int *a,int p,int r);

void GreedySelector(int n,int *s,int *f,int *A); int main() { int n=0,i; while(n<=0||n>50) { printf("\n"); printf("请输入活动的个数,n="); scanf("%d",&n); if(n<=0) printf("请输入大于零的数!"); else if(n>50) printf("请输入小于50的数!"); } printf("\n请分别输入开始时间s[i]和结束时间f[i]:\n\n"); for(i=1;i<=n;i++) { printf("s[%d]=",i,i); scanf("%d",&s[i]); printf("f[%d]=",i,i); scanf("%d",&f[i]); printf("\n"); } QuickSort(s,f,1,n); //按结束时间非减序排列

贪心算法经典例题

贪心算法经典例题 所谓贪心算法指的是为了解决在不回溯的前提之下,找出整体最优或者接近最优解的这样一种类型的问题而设计出来的算法。贪心算法的基本思想是找出整体当中每个小的局部的最优解,并且将所有的这些局部最优解合起来形成整体上的一个最优解。因此能够使用贪心算法的问题必须满足下面的两个性质:1.整体的最优解可以通过局部的最优解来求出;2.一个整体能够被分为多个局部,并且这些局部都能够求出最优解。使用贪心算法当中的两个典型问题是活动安排问题和背包问题。 利用贪心算法解题,需要解决两个问题: 一是问题是否适合用贪心法求解。我们看一个找币的例子,如果一个货币系统有3种币值,面值分别为一角、五分和一分,求最小找币数时,可以用贪心法求解;如果将这三种币值改为一角一分、五分和一分,就不能使用贪心法求解。用贪心法解题很方便,但它的适用范围很小,判断一个问题是否适合用贪心法求解,目前还没有一个通用的方法,在信息学竞赛中,需要凭个人的经验来判断何时该使用贪心算法。 二是确定了可以用贪心算法之后,如何选择一个贪心标准,才能保证得到问题的最优解。在选择贪心标准时,我们要对所选的贪心标准进行验证才能使用,不要被表面上看似正确的贪心标准所迷惑,如下面的例子。

例2 (NOIP1998tg)设有n个正整数,将他们连接成一排,组成一个最大的多位整数。例如:n=3时,3个整数13,312,343,连成的最大整数为:34331213 又如:n=4时,4个整数7,13,4,246连接成的最大整数为7424613 输入:N N个数 输出:连接成的多位数 算法分析:此题很容易想到使用贪心法,在考试时有很多同学把整数按从大到小的顺序连接起来,测试题目的例子也都符合,但最后测试的结果却不全对。按这种贪心标准,我们很容易找到反例:12,121 应该组成12121而非12112,那么是不是相互包含的时候就从小到大呢?也不一定,如:12,123 就是12312而非12112,这样情况就有很多种了。是不是此题不能用贪心法呢? 其实此题是可以用贪心法来求解,只是刚才的贪心标准不对,正确的贪心标准是:先把整数化成字符串,然后再比较a+b和b+a,如果a+b>b+a,就把a排在b的前面,反之则把a排在b的后面。 源程序: var s:array[1..20] of string; t:string;i,j,k,n:longint; begin

相关文档
最新文档