文档库 最新最全的文档下载
当前位置:文档库 › 实验二 贪心算法-最少活动会场安排问题

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

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

中原工学院计算机学院

实验报告

实验项目名称实验二、最少活动会场安排问题课程名称算法设计与分析

学生姓名梁斐燕

学生学号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;

}

}

㈡、函数调用及主函数设计

(可用函数的调用关系图说明)

主函数

快排选择活动

㈢程序调试及运行结果分析

㈣实验总结

在做本实验之前,自己看了课本上所列举的贪心法解活动安排问题的代码,代码很简单,很容易理解,于是就按课本的代码实现。通过几个测试用例测试发现结果不对,后来发现自己忘了进行贪心法的一个前提条件,事先没有按各个活动结束时间对所有活动进行非递减排序,所以才会导致结果错误。经过修正后,自己真正理解了贪心法解活动安排问题的原理。

四、主要算法流程图及程序清单

1、主要算法流程图:

快速排序产生中间数贪心算法实现活动安排主函数调用

2、程序清单

(程序过长,可附主要部分)

#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存储所有的*/

void GreedySelector(int n, int *s, int *f, int *A);

int Partition(int *b, int *a, int p, int r)

{

int k, m, y, i = p, j = r + 1;

int x = a[p]; y = b[p];

while (1) {

while (a[++i]

while (a[--j]>x);

if (i >= j)

break;

else {

k = a[i]; a[i] = a[j]; a[j] = k; m = b[i]; b[i] = b[j]; b[j] = m;

}

}

a[p] = a[j];

b[p] = b[j];

a[j] = x;

b[j] = y;

return j;

}

void QuickSort(int *b, int *a, int p, int r)

{

int q; if (p

{

q = Partition(b, a, p, r);

QuickSort(b, a, p, q - 1);/*对左半段排序*/

QuickSort(b, a, q + 1, r);/*对右半段排序*/

}

} //产生中间数

int main()

{

int n = 0, i;

while (n <= 0 || n>50)

{

printf("\n");

printf("请输入活动的个数:");

scanf_s("%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_s("%d", &s[i]);

printf("f[%d]=", i, i);

scanf_s("%d", &f[i]);

printf("\n");

}

QuickSort(s, f, 1, n); //按结束时间非减序排列

printf("按结束时间非减序排列如下:\n"); /*输出排序结果*/

printf("\n 序号\t开始时间结束时间\n");

printf("-------------------------\n"); for (i = 1; i <= n; i++)

printf(" %d\t %d\t %d\n", i, s[i], f[i]);

printf("-------------------------\n");

GreedySelector(n, s, f, A);//贪心算法实现活动安排

printf("安排的活动序号依次为:");

for (i = 1; i <= n; i++)

{

if (A[i])

printf("\n%d ", i);

} printf("\n");

system("pause");

return 0;

} //快速排序

//产生中间数

//贪心算法实现活动安排

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;

}

}

算法分析与设计(线下作业二)

《算法分析与设计》 学习中心: 专业: 学号: 姓名:

作业练习二 一、名词解释 1、MST性质 2、子问题的重叠性质 递归算法求解问题时,每次产生的子问题并不总是新问题,有些子问题被反复计算多次,这种性质称为子问题的重叠性质。 二、简答题 1、简述动态规划算法求解的基本要素。 答:动态规划算法求解的基本要素包括: 1)最优子结构是问题能用动态规划算法求解的前提; 2)动态规划算法,对每一个子问题只解一次,而后将其解保存在一个表格中,当再次需要解此子问题时,只是简单地用常数时间查看一下结果,即重叠子问题。 2、备忘录方法和动态规划算法相比有何异同简述之。 答:备忘录方法是动态规划算法的变形。与动态规划算法一样,备忘录方法用表格保存已解决的子问题的答案,在下次需要解此问题时,只要简单地查看该子问题的解答,而不必重新计算。备忘录方法与动态规划算法不同的是,备忘录方法的递归方式是自顶向下的,而动态规划算法则是自底向上递归的。因此,备忘录方法的控制结构与直接递归方法的控制结构相同,区别在于备忘录方法为每个解过的子问题建立了备忘录以备需要时查看,避免了相同的子问题的重复求解,而直接递归方法没有此功能。

3、贪心算法求解的问题主要具有哪些性质简述之。 答:贪心算法求解的问题一般具有二个重要的性质: 一是贪心选择性质,这是贪心算法可行的第一个基本要素; 另一个是最优子结构性质,问题的最优子结构性质是该问题可用贪心算法求解的关键特征。 三、算法编写及算法应用分析题 1、设计求解如下最大子段和问题的动态规划算法。只需给出其递推计算公式即可。 最大子段和问题:给定由n 个整数(可能为负整数)组成的序列a1a2 … an,求该序列形如Σi≤k≤j ak的子段和的最大值。当所有整数均为负整数时定义其最大子段和为0。依次定义,所求的最优值为max{0, max1≤i≤j≤n Σi≤k≤j ak }。

算法设计与分析实验报告贪心算法

算法设计与分析实验报告 贪心算法 班级:2013156 学号:201315614 姓名:张春阳哈夫曼编码 代码 #include float small1,small2; int flag1,flag2,count; typedefstructHuffmanTree { float weight; intlchild,rchild,parent; }huffman; huffmanhuffmantree[100]; void CreatHuffmanTree(intn,int m) { inti; void select(); printf("请输入%d个节点的权值:",n); for(i=0;i

printf("\n"); for(i=0;i

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

贪心算法会场安排问题算法设计分析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

贪心算法经典例题

贪心算法经典例题 发布日期:2009-1-8 浏览次数:1180 本资料需要注册并登录后才能下载! ·用户名密码验证码找回密码·您还未注册?请注册 您的账户余额为元,余额已不足,请充值。 您的账户余额为元。此购买将从您的账户中扣除费用0.0元。 内容介绍>> 贪心算法经典例题 在求最优解问题的过程中,依据某种贪心标准,从问题的初始状态出发,直接去求每一步的最优解,通过若干次的贪心选择,最终得出整个问题的最优解,这种求解方法就是贪心算法。 从贪心算法的定义可以看出,贪心法并不是从整体上考虑问题,它所做出的选择只是在某种意义上的局部最优解,而由问题自身的特性决定了该题运用贪心算法可以得到最优解。 我们看看下面的例子 例1 均分纸牌(NOIP2002tg) [问题描述] 有 N 堆纸牌,编号分别为 1,2,…, N。每堆上有若干张,但纸牌总数必为 N 的倍数。可以在任一堆上取若干张纸牌,然后移动。移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上;在编号为 N 的堆上取的纸牌,只能移到编号为 N-1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。例如 N=4,4 堆纸牌数分别为: ①9 ②8 ③17 ④ 6 移动3次可达到目的: 从③取 4 张牌放到④(9 8 13 10) -> 从③取 3 张牌放到②(9 11 10 10)-> 从②取 1 张牌放到①(10 10 10 10)。 [输入]:键盘输入文件名。 文件格式:N(N 堆纸牌,1 <= N <= 100) A1 A2 … An (N 堆纸牌,每堆纸牌初始数,l<= Ai <=10000) [输出]:输出至屏幕。格式为:所有堆均达到相等时的最少移动次数。 [输入输出样例] a.in: 4 9 8 17 6 屏慕显示:3 算法分析:设a[i]为第i堆纸牌的张数(0<=i<=n),v为均分后每堆纸牌的张数,s为最小移到次数。 我们用贪心法,按照从左到右的顺序移动纸牌。如第i堆(0

实验3. 贪心算法

实验3.贪心算法 一、实验目的 1.理解贪心算法的基本思想。 2.运用贪心算法解决实际问题。 二、实验环境与地点 1.实验环境:Windows7,Eclipse 2.实验地点:网络工程实验室 三、实验内容与步骤 编写程序完成下列题目,上机调试并运行成功。 1.活动安排问题。 问题:有n个活动的集合A={1,2,…,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。 求解:安排尽量多项活动在该场地进行,即求A的最大相容子集。 设待安排的11个活动的开始时间和结束时间按结束时间的升序排列如下: 将此表数据作为实现该算法的测试数据。 (1)给出算法基本思想; (2)给出用java语言实现程序的代码; 算法: public static int greedySelector(int[] s, int[] f, boolean a[]) { 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; }

2.哈夫曼编码是广泛地用于数据文件压缩的十分有效的编码方法。统计字符串中各个字符 出现的频率,求各个字符的哈夫曼编码方案。 输入:good good study,day day up 输出:各字符的哈夫曼编码。 算法: 算法中用到的类Huffman定义为: private static class Huffman implements Comparable { Bintree tree; float weight;// 权值 private Huffman(Bintree tt, float ww) { tree = tt; weight = ww; } public int compareTo(Object x) { float xw = ((Huffman) x).weight; if (weight < xw) return -1; if (weight == xw) return 0; return 1; } } 算法huffmanTree描述如下: public static Bintree huffmanTree(float[] f) { // 生成单结点树 int n = f.length; Huffman[] w = new Huffman[n + 1]; Bintree zero = new Bintree(); for (int i = 0; i < n; i++) { Bintree x = new Bintree(); x.makeTree(new MyInteger(i), zero, zero); w[i + 1] = new Huffman(x, f[i]); } // 建优先队列 MinHeap H = new MinHeap(); H.initialize(w, n); // 反复合并最小频率树 for (int i = 1; i < n; i++) { Huffman x = (Huffman) H.removeMin(); Huffman y = (Huffman) H.removeMin(); Bintree z = new Bintree();

实验二(贪心算法)

华东师范大学计算机科学技术系上机实践报告 课程名称:算法设计与分析年级:05上机实践成绩: 指导教师:柳银萍姓名:张翡翡 上机实践名称:贪心算法学号:10052130119上机实践日期:2007-4-10 上机实践编号:NO.2组号:上机实践时间:10:00-11:30 一、目的 了解熟悉掌握贪心算法实质并学会灵活运用,从而解决生活中一些实际问题。 二、内容与设计思想 1.超市的自动柜员机(POS)要找给顾客各种数值的现金,表面上看,这是一个很简单的任务,但交给机器办就不简单了。你作为一个计算机专家,要求写一个程序来对付这个“简单”的问题。 你的自动柜员机有以下的币种:100元,50元,20元,10元,5元,2元,1元。你可以假设每种钱币的数量是无限的。现在有一笔交易,需要找个客户m元,请你设计一个算法,使得找给顾客的钱币张数最少。 要求: 输入:第一行仅有一个整数n(0

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

算法分析与设计实验报告第一次附加实验

附录: 完整代码(贪心法) //贪心算法最小生成树prim算法 #include #include #include #include #include using namespace std; #define inf 9999; //定义无限大的值const int N=6; template //模板定义 void Prim(int n,Type c[][N+1]); int main() { int c[N+1][N+1]; cout<<"连通带权图的矩阵为:"<

cin>>c[i][j]; } } cout<<"Prim算法最小生成树选边次序如下:"< //参数为结点个数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

贪心法 多机调度问题

//多机调度问题 /* 贪心法求解多级调度问题的贪心策略师最长处理时间的作业优先,即把处理时间最长的作业分配给最先空闲的机器,这样就可以保证处理时间长的 作业优先处理,从而在整体上获得尽可能短的时间。按照最长处理时间作业优先的贪心测落,当m>n,时,只要将机器ide [0,ti)时间去见分配给作业j即可, 当m using namespace std; void lowsort(int *t,int *p,int n)//将数组t[n]按从小到大的顺序排序,相应的任务编号数组p[n]也要随之改变 { int index; for(int 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;//终止时间如果前一个大于后一个就交换位置

2009.1算法设计与分析课程期末试卷-A卷(自测 )

华南农业大学期末考试试卷(A卷)2008学年第一学期考试科目:算法分析与设计 考试类型:(闭卷)考试时间:120 分钟 学号姓名年级专业 一、选择题(20分,每题2分) 1.下述表达不正确的是。 A.n2/2 + 2n的渐进表达式上界函数是O(2n) B.n2/2 + 2n的渐进表达式下界函数是Ω(2n) C.logn3的渐进表达式上界函数是O(logn) D.logn3的渐进表达式下界函数是Ω(n3) 2.当输入规模为n时,算法增长率最大的是。 A.5n B.20log 2n C.2n2 D.3nlog 3 n 3.T(n)表示当输入规模为n时的算法效率,以下算法效率最优的是。A.T(n)= T(n – 1)+1,T(1)=1 B.T(n)= 2n2 C.T(n)= T(n/2)+1,T(1)=1 D.T(n)= 3nlog 2 n 4.在棋盘覆盖问题中,对于2k×2k的特殊棋盘(有一个特殊方块),所需的L型骨 牌的个数是。 A.(4k– 1)/3 B.2k /3 C.4k D.2k 5.在寻找n个元素中第k小元素问题中,若使用快速排序算法思想,运用分治算

法对n个元素进行划分,应如何选择划分基准?下面答案解释最合理。 A.随机选择一个元素作为划分基准 B.取子序列的第一个元素作为划分基准 C.用中位数的中位数方法寻找划分基准 D.以上皆可行。但不同方法,算法复杂度上界可能不同 6.有9个村庄,其坐标位置如下表所示: 现在要盖一所邮局为这9个村庄服务,请问邮局应该盖在才能使到邮局到这9个村庄的总距离和最短。 A.(4.5,0)B.(4.5,4.5)C.(5,5)D.(5,0) 7.n个人拎着水桶在一个水龙头前面排队打水,水桶有大有小,水桶必须打满水, 水流恒定。如下说法不正确? A.让水桶大的人先打水,可以使得每个人排队时间之和最小 B.让水桶小的人先打水,可以使得每个人排队时间之和最小 C.让水桶小的人先打水,在某个确定的时间t内,可以让尽可能多的人打上水D.若要在尽可能短的时间内,n个人都打完水,按照什么顺序其实都一样 8.分治法的设计思想是将一个难以直接解决的大问题分割成规模较小的子问题, 分别解决子问题,最后将子问题的解组合起来形成原问题的解。这要求原问题和子问题。

实验 1 贪心算法实现最小生成树

实验一用贪心算法实现最小生成树问题 一.实验目的 1.熟悉贪心算法的基本原理和使用范围。 二.实验内容及要求 内容:任选一种贪心算法(prim或Kruskal),求解最小生成树。对算法进行编程。 要求:使用贪心算法编程,求解最小生成树问题 三.程序列表 (1)prim算法 #include #define INF 32766 #define max 40 void prim(int g[][max],int n) { int lowcost[max],closest[max]; int i,j,k,min; for(i=2;i<=n;i++) { lowcost[i]=g[1][i]; closest[i]=1; } lowcost[1]=0; for(i=2;i<=n;i++) { min=INF; k=0; for(j=2;j<=n;j++) { if((lowcost[j]

for(j=2;j<=n;j++) { if(g[k][j]

贪心算法求解最优服务次序问题

实验名称:贪心算法实例编程 求解最优服务次序问题 1、实验目的: 1)理解贪心算法的概念 2)掌握贪心算法的基本要素 3)掌握设计贪心算法的一般步骤 4)针对具体问题,能应用贪心算法设计有效算法 5)用C++实现算法,并且分析算法的效率 2、实验设备及材料: 硬件设备:PC机 机器配置:双核cpu频率2.2GHz,内存2G 操作系统:Windows 7 开发工具:VC++6.0 3、实验内容: ①问题描述 设有n个顾客同时等待一项服务。顾客i需要的服务时间为t i,1≤i≤n。 应如何安排n个顾客的服务次序才能使平均等待时间达到最小?平均等待时间是n恶搞顾客等待服务时间的总和除以n。 ②编程任务 对于给定的n个顾客需要的服务时间,计算最优服务次序。 ③样例 例如,现在有5个顾客,他们需要的服务时间分别为:56,12,5,99,33。 那么,按照所需服务时间从小到大排序为:5,12,33,56,99。排序后的顾客等待服务完成的时间为:5,17,50,106,205;和为:383;平均等待时间为:76.6。

4、实验方法步骤及注意事项: ①实验步骤 a、分析问题,确定最优的贪心选择; b、针对贪心选择过程进行算法设计; c、举例验证算法的正确性; d、上机调试算法。 ②解题思路 1)求解最优服务次序问题的贪心策略为:先为所需服务时间最短的顾客服务。 2)使用贪心算法求解最优服务次序问题的算法,用C++语言描述。 ①.最优值:(贪心算法) text(int n,int x[],int s[])//s[]为保存每个顾客等待时间的数组 { int i; int sum=0; for(i=0;i0){ s[i]=x[i]+s[i-1]; sum+=s[i];} else { s[i]=x[i]; sum+=s[i]; } } return sum/n; } ②.最优解:(快速排序) void QuickSort(int e[], int first, int end) { int i=first,j=end,key=e[first]; while(i=key) j--; e[i]=e[j]; while(ii+1) QuickSort(e,i+1,end); }

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

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

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

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

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

实验二 贪心算法的应用

实验二贪心算法的应用 一、实验目的 1.掌握贪心算法的基本概念和两个基本要素 2.熟练掌握贪心算法解决问题的基本步骤。 3.学会利用贪心算法解决实际问题。 二、实验内容 1.问题描述: 题目二:会场安排问题 假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。设计一个有效的贪心算法来进行安排。试编程实现对于给定的k个待安排活动,计算使用的最少会场。输入数据中,第一行是k的值,接下来的k行中,每行有2个正整数,分别表示k个待安排活动的开始时间和结束时间,时间以0点开始的分钟计。输出为最少的会场数。 输入数据示例 5 1 23 12 28 25 35 27 80 36 50 输出数据 3 三、算法分析 Stept1:输入各个活动的开始时间(s)和结束时间(e),初始化各活动的会场号。Step2:按活动的开始时间和活动时间排序,s最早(第一优先级)和持续时间最短(第二优先级)的活动排在最前。 Step3:执行贪婪算法,即s最早和持续时间最短的优先安排会场,并记录会场号,其余活动的s大于或等于已安排活动的e的安排在同一会场,若某活动的s

小于安排活动的e,则安排在另一会场,记录会场号,依次循环,直到所有活动均被安排。 Step4:统计会场号数,输出。 时间复杂度:O(n) 算法时间:O(nlogn) 核心算法: void swap(Active &a,Active&b) { Active t; t=a; a=b; b=t; } //活动时间排序 for(i=1;i<=k;i++) { for(j=i;j<=k;j++) { if(a[i].s>a[j].s) swap(a[i],a[j]); if(a[i].s==a[j].s) { if(a[i].e>a[j].e) swap(a[i],a[j]); } } } 四、程序调试及运行结果分析 五、源代码

算法设计与分析课程大作业

题目作业调度问题及算法分析 学院名称:计算机与信息工程学院 专业名称:计算机科学与技术

目录 《算法设计与分析》课程大作业.................................................................... 错误!未定义书签。一.动态规划算法解决流水作业调度. (4) 1、问题描述 (4) 2、算法分析 (4) 3. 算法的描述 (5) 4、部分算法实现 (6) 5. 运行结果 (8) 6、时空效率分析 (8) 二.贪心算法解多机调度问题 (8) 1、问题描述 (8) 2、算法分析 (9) 3.部分算法实现 (9) 4.计算复杂性分析 (11) 5. 运行结果 (12) 三.回溯法解决批作业调度问题 (12) 1.问题描述 (12) 2.算法思想 (13) 3. 部分算法实现 (14) 4.运行结果 (15) 5.时间复杂性分析 (15) 四.作业调度算法比较 (16) 五.课程学习总结 (16)

摘要: 在现代企业中,作业调度已成为提高资源利用率、从而提高企业运行效益的关键环节之一。把各个作业分配到车间现有的设备上,并确定它们的先后次序,这是一项复杂的工作本文就作业调度排序问题进行了研究,通过对几个经典作业调度算法的分析讨论,总结了各个算法对作业调度的求解过程,并给出了每个算法的复杂度及性能分析。 关键词:作业调度;动态规划;贪心算法;回溯法;

一.动态规划算法解决流水作业调度 1、问题描述 给定n 个作业,每个作业有两道工序,分别在两台机器上处理。一台机器一次只能处理一道工序,并且一道工序一旦开始就必须进行下去直到完成。一个作业只有在机器1上的处理完成以后才能由机器2处理。假设已知作业i 在机器j 上需要的处理时间为t[i,j]。流水作业调度问题就是要求确定一个作业的处理顺序使得尽快完成这n 个作业。 2、算法分析 直观上,一个最优调度应使机器M1没有空闲时间,且机器M2的空闲时间最少。在一般情况下,机器M2上会有机器空闲和作业积压2种情况。 在一般情况下,机器M1开始加工S 中作业时,机器M2还在加工其他作业,要等时间t 后才可利用。将这种情况下完成S 中作业所需的最短时间记为T(S,t)。流水作业调度问题的最优值为T(N,0)。 由流水作业调度问题的最优子结构性质可知, )}},{({min )0,(1i i n i b i N T a N T -+=≤≤(1)

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

实验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]);

计算机算法与分析贪心算法实验报告

实验03 贪心算法 一、实验目的 1.掌握贪心算法的基本思想 2.掌握贪心算法中贪心选择性质和最优子结构性质的分析与证明 3.掌握贪心算法求解问题的方法 二、实验内容 1.认真阅读算法设计教材,了解贪心算法思想及方法; 2.设计用贪心算法求解最优装载哈夫曼编码、单源最短路径、最小生成树的 java程序 三、求解的问题 1.哈夫曼编码是广泛地用于数据文件压缩的十分有效的编码方法。给出文件中 各个字符出现的频率,求各个字符的哈夫曼编码方案。 2.给定带权有向图G =(V,E),其中每条边的权是非负实数。另外,还给定V 中的一个顶点,称为源。现在要计算从源到所有其他各顶点的最短路长度。 这里路的长度是指路上各边权之和。 3.设G =(V,E)是无向连通带权图,即一个网络。E中每条边(v,w)的权为 c[v][w]。如果G的子图G’是一棵包含G的所有顶点的树,则称G’为G的生成树。生成树上各边权的总和称为该生成树的耗费。在G的所有生成树中,耗费最小的生成树称为G的最小生成树。求G的最小生成树。 四、实验程序 1.哈夫曼编码 哈夫曼算法以自底向上的方式构造表示最优前缀码的二叉树T。算法以|C|个叶结点开始,执行|C|-1次的“合并”运算后产生最终所要求的树T。下面所给出的算法huffmanTree中,编码字符集中的每一字符c的频率是f(c)。以f 为键值的优先队列Q用在贪心选择时有效地确定算法当前要合并的两棵具有最小频率的树。一旦两棵具有最小频率的树合并后,产生一棵新的树,其频率为合并两棵树的频率之和,并将新树插入优先队列Q。 private static class Huffman implements Comparable{ Bintree tree; float weight; private Huffman(Bintree tt,float ww) { tree=tt;weight=ww; } public int compareTo(Object x){ float xw=((Huffman) x).weight; if(weight

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

《算法分析与设计》实验报告完成日期:20011.11.17

实验目的 (1)了解贪心算法思想 (2)掌握贪心法典型问题,如背包问题、作业调度问题等。 实验内容 (1)编写一个简单的程序,实现单源最短路径问题。 (2)编写一段程序,实现找零。 【问题描述】当前有面值分别为2角5分,1角,5分,1分的硬币,请给出找n分钱的最佳方案(要求找出的硬币数目最少)。 (3)编写程序实现多机调度问题 【问题描述】要求给出一种作业调度方案,使所给的n个作业在尽可能短的时间内由m台机器加工处理完成。约定,每个作业均可在任何一台机器上加工处理,但未完工前不允许中断处理。作业不能拆分成更小的子作业。 算法思想分析 ⑴所谓单源最短路径问题是指:已知图G=(V,E),我们希望找出从某给定的源结点S∈V到V中的每个结点的最短路径。 首先,我们可以发现有这样一个事实:如果P是G中从vs到vj的最短路,vi是P中的一个点,那么,从vs沿P到vi的路是从vs到vi的最短路。 (一)Dijkstra算法 对于图G,如果所有Wij≥0的情形下,目前公认的最好的方法是由Dijkstra于1959年提出来的。 例1 已知如下图所示的单行线交通网,每弧旁的数字表示通过这条单行线所需要的费用,现在某人要从v1出发,通过这个交通网到v8去,求使总费用最小的旅行路线。 Dijkstra方法的基本思想是从vs出发,逐步地向外探寻最短路。执行过程中,与每个点对应,记录下一个数(称为这个点的标号),它或者表示从vs 到该点的最短路的权(称为P标号)、或者是从vs到该点的最短路的权的上界(称为T标号),方法的每一步是去修改T标号,并且把某一个具T标号的改变为具P标号的点,从而使G中具P标号的顶点数多一个,这样至多经过n-1(n为图G的顶点数)步,就可以求出从vs到各点的最短路。 在叙述Dijkstra方法的具体步骤之前,以例1为例说明一下这个方法的基本思想。例1中,s=1。因为所有Wij≥0,故有d(v1, v1)=0。这时,v1是具P标号的点。现在考察从v1发出的三条弧,(v1, v2), (v1, v3)和(v1, v4)。如果某人从v1出发沿(v1, v2)到达v2,这时需要d(v1, v1)+w12=6单位的费用;如果他从v1出发沿(v1, v3)到达v3,这时需要d(v1, v1)+w13=3单位的费用;类似地,若沿(v1, v4)到达v4,这时需要d(v1, v1)+w14=1单位的费用。因为min{ d(v1, v1)+w12,d(v1,

相关文档
相关文档 最新文档