算法分析与设计实验报告 实验5:贪心算法的应用
- 格式:docx
- 大小:22.58 KB
- 文档页数:5
贪心算法实验报告贪心算法实验报告引言:贪心算法是一种常用的算法设计策略,它通常用于求解最优化问题。
贪心算法的核心思想是在每一步选择中都选择当前最优的解,从而希望最终能够得到全局最优解。
本实验旨在通过实际案例的研究,探索贪心算法的应用和效果。
一、贪心算法的基本原理贪心算法的基本原理是每一步都选择当前最优解,而不考虑整体的最优解。
这种贪婪的选择策略通常是基于局部最优性的假设,即当前的选择对于后续步骤的选择没有影响。
贪心算法的优点是简单高效,但也存在一定的局限性。
二、实验案例:零钱兑换问题在本实验中,我们以零钱兑换问题为例,来说明贪心算法的应用。
问题描述:假设有不同面值的硬币,如1元、5元、10元、50元和100元,现在需要支付给客户x元,如何用最少的硬币数完成支付?解决思路:贪心算法可以通过每次选择当前面值最大的硬币来求解。
具体步骤如下:1. 初始化一个空的硬币集合,用于存放选出的硬币。
2. 从面值最大的硬币开始,如果当前硬币的面值小于等于待支付金额,则将该硬币放入集合中,并将待支付金额减去该硬币的面值。
3. 重复步骤2,直到待支付金额为0。
实验过程:以支付金额为36元为例,我们可以通过贪心算法求解最少硬币数。
首先,面值最大的硬币为100元,但36元不足以支付100元硬币,因此我们选择50元硬币。
此时,剩余待支付金额为36-50=-14元。
接下来,面值最大的硬币为50元,但待支付金额为负数,因此我们选择下一个面值最大的硬币,即10元硬币。
此时,剩余待支付金额为-14-10=-24元。
继续选择10元硬币,剩余待支付金额为-24-10=-34元。
再次选择10元硬币,剩余待支付金额为-34-10=-44元。
最后,选择5元硬币,剩余待支付金额为-44-5=-49元。
由于待支付金额已经为负数,我们无法继续选择硬币。
此时,集合中的硬币数为1个50元和3个10元,总共4个硬币。
实验结果:通过贪心算法,我们得到了36元支付所需的最少硬币数为4个。
XX师大学计算机与信息工程学院算法设计与分析结课论文题目贪心算法的分析与实际应用专业计算机科学与技术班级1402班学号1430090056XX王悦宁任课教师洋完成日期2015-1-18贪心算法的分析与实际应用王悦宁摘要:贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择。
也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。
贪心算法不是对所有问题都能得到整体最优解,但对围相当广泛的许多问题他能产生整体最优解或者是整体最优解的近似解。
本文主要介绍了贪心算法的核心、特点及算法本身存在的问题。
关键词:贪心算法;最优解;背包问题;马踏棋盘The greedy algorithm analysis and practical application王悦宁Tianjin normal university puter and Information Engineering College Tianjin 300387Abstract:Greedy algorithm refers to, in the solution of the problem, always make in the current view is the best choice. That is to say, not to be considered as a whole, he made only in a sense of the local optimal solution. The greedy algorithm is not able to obtain the global optimal solution for all problems, but for a wide range of problems, he can produce the global optimal solution or the approximate solution of the global optimal solution. This paper mainly introduces the core of the greedy algorithm, the characteristics and the existing problems of the algorithm itself..Key words:greedy algorithm; optimal solution; knapsack problem;0引言研究背景:为了满足人们对大数据量信息处理的渴望,为了解决各种实际问题,计算机算法学得到了飞速的发展,线性规划、动态规划、贪心策略等一系列运筹学模型纷纷运用到计算机算法学中,产生了解决各种现实问题的有效算法。
算法设计与分析实验报告算法设计与分析实验报告引言:算法设计与分析是计算机科学中的重要课程,它旨在培养学生解决实际问题的能力。
本次实验旨在通过设计和分析不同类型的算法,加深对算法的理解,并探索其在实际应用中的效果。
一、实验背景算法是解决问题的步骤和方法的描述,是计算机程序的核心。
在本次实验中,我们将重点研究几种经典的算法,包括贪心算法、动态规划算法和分治算法。
通过对这些算法的设计和分析,我们可以更好地理解它们的原理和应用场景。
二、贪心算法贪心算法是一种基于局部最优选择的算法,它每一步都选择当前状态下的最优解,最终得到全局最优解。
在实验中,我们以背包问题为例,通过贪心算法求解背包能够装下的最大价值物品。
我们首先将物品按照单位重量的价值从大到小排序,然后依次将能够装入背包的物品放入,直到背包无法再装下物品为止。
三、动态规划算法动态规划算法是一种通过将问题分解为子问题,并记录子问题的解来求解整体问题的算法。
在实验中,我们以斐波那契数列为例,通过动态规划算法计算斐波那契数列的第n项。
我们定义一个数组来保存已经计算过的斐波那契数列的值,然后通过递推公式将前两项的值相加得到后一项的值,最终得到第n项的值。
四、分治算法分治算法是一种将问题分解为更小的子问题,并通过递归求解子问题的算法。
在实验中,我们以归并排序为例,通过分治算法对一个无序数组进行排序。
我们首先将数组分成两个子数组,然后对子数组进行递归排序,最后将两个有序的子数组合并成一个有序的数组。
五、实验结果与分析通过对以上三种算法的设计和分析,我们得到了以下实验结果。
在贪心算法中,我们发现该算法能够在有限的时间内得到一个近似最优解,但并不能保证一定得到全局最优解。
在动态规划算法中,我们发现该算法能够通过记忆化搜索的方式得到准确的结果,但在问题规模较大时,其时间复杂度较高。
在分治算法中,我们发现该算法能够将问题分解为更小的子问题,并通过递归求解子问题,最终得到整体问题的解。
《算法设计与分析》课程实验报告实验序号:07实验项目名称:实验8 贪心算法(一)一、实验题目1.删数问题问题描述:键盘输入一个高精度的正整数N(不超过250 位),去掉其中任意k个数字后剩下的数字按原左右次序将组成一个新的非负整数。
编程对给定的N 和k,寻找一种方案使得剩下的数字组成的新数最小。
若输出前有0则舍去2.区间覆盖问题问题描述:设x1,x2,...xn是实轴上的n个点。
用固定长度为k的闭区间覆盖n个点,至少需要多少个这样的固定长度的闭区间?请你设计一个有效的算法解决此问题。
3.会场安排问题问题描述:假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。
设计一个有效的贪心算法进行安排。
(这个问题实际上是著名的图着色问题。
若将每一个活动作为图的一个顶点,不相容活动间用边相连。
使相邻顶点着有不同颜色的最小着色数,相应于要找的最小会场数。
)4.导弹拦截问题问题描述:某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。
但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。
某天,雷达捕捉到敌国的导弹来袭。
由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
给定导弹依次飞来的高度(雷达给出的高度数据是≤50000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
二、实验目的(1)通过实现算法,进一步体会具体问题中的贪心选择性质,从而加强对贪心算法找最优解步骤的理解。
(2)掌握通过迭代求最优的程序实现技巧。
(3)体会将具体问题的原始数据预处理后(特别是以某种次序排序后),常能用贪心求最优解的解决问题方法。
三、实验要求(1)写出题1的最优子结构性质、贪心选择性质及相应的子问题。
(2)给出题1的贪心选择性质的证明。
(3)(选做题):写出你的算法的贪心选择性质及相应的子问题,并描述算法思想。
一、实验背景贪心算法是一种在每一步选择中都采取当前状态下最好或最优的选择,从而希望导致结果是全局最好或最优的算法策略。
贪心算法并不保证能获得最优解,但往往能获得较好的近似解。
在许多实际应用中,贪心算法因其简单、高效的特点而被广泛应用。
本实验旨在通过编写贪心算法程序,解决经典的最小生成树问题,并分析贪心算法的优缺点。
二、实验目的1. 理解贪心算法的基本原理和应用场景;2. 掌握贪心算法的编程实现方法;3. 分析贪心算法的优缺点,并尝试改进;4. 比较贪心算法与其他算法在解决最小生成树问题上的性能。
三、实验内容1. 最小生成树问题最小生成树问题是指:给定一个加权无向图,找到一棵树,使得这棵树包含所有顶点,且树的总权值最小。
2. 贪心算法求解最小生成树贪心算法求解最小生成树的方法是:从任意一个顶点开始,每次选择与当前已选顶点距离最近的顶点,将其加入生成树中,直到所有顶点都被包含在生成树中。
3. 算法实现(1)数据结构- 图的表示:邻接矩阵- 顶点集合:V- 边集合:E- 已选顶点集合:selected- 最小生成树集合:mst(2)贪心算法实现```def greedy_mst(graph):V = set(graph.keys()) # 顶点集合selected = set() # 已选顶点集合mst = set() # 最小生成树集合for i in V:selected.add(i)mst.add((i, graph[i]))while len(selected) < len(V):min_edge = Nonefor edge in mst:u, v = edgeif v not in selected and (min_edge is None or graph[u][v] < graph[min_edge[0]][min_edge[1]]):min_edge = edgeselected.add(min_edge[1])mst.add(min_edge)return mst```4. 性能分析为了比较贪心算法与其他算法在解决最小生成树问题上的性能,我们可以采用以下两种算法:(1)Prim算法:从任意一个顶点开始,逐步添加边,直到所有顶点都被包含在生成树中。
贪心算法_实验报告一、设计分析●问题描述:键盘输入一个高精度的正整数N(N不超过240位),去掉其中任意S个数字后剩下的数字按原左右次序将组成一个新的正整数。
编程对给定的N和S,寻找一种方案使得剩下的数字组成的新数最小。
●设计思路:在位数固定的前提下,让高位的数字尽量小其值就较小,依据此贪心策略解决此问题。
删除高位较大的数字。
具体:相邻两位比较若高位比低位大则删除高位。
删除字符的方法:1)物理删除,用后面的字符覆盖已删除的字符。
有比较多字符移动操作,算法效率不高。
2)用数组记录字符的状态,“1”表示对应数字存在,“0”表示对应数字已删除。
3)利用数组,记录未删除字符的下标:n=“1 2 4 3 5 8 3 3”0 0 0 0 0 04比3大删除“1 2 3 5 8 3 3” 1 2 4 5 0 08比3大删除“1 2 3 5 3 3” 1 2 4 5 05比3大删除“1 2 3 3 3” 1 2 4 7 8二、程序代码c语言实现#include<stdio.h>#include<string.h>#define N 10000int main(void){char a[N];int i,j,k,n;printf("输入要处理的数据:\n");gets(a);printf("输入要删除的数字个数:\n");scanf("%d",&n);三、测试用例四、实验总结加深了对贪心算法的理解与运用。
所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。
这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。
动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。
《算法分析与设计》实验报告专业:计科班级:日期:2016/04/11 成绩:学生姓名:学号:指导老师:实验单元三贪心算法一、实验题目实验一最小生成树二、实验目的熟悉贪心算法的基本原理与使用范围;熟悉和掌握贪心算法求最小生成树问题。
三、实验内容给定一个带权图G = (V, E),求G的最小生成树。
Kruskal算法的基本思想是:对所有的边进行排序,然后依次加入顶点,如果不构成回路,就加入,否则舍弃这条边,得到的最终图变成一棵树,即为最小生成树。
四、实验结果(代码及运行结果)实验建立的无线图如下图所示:实验源代码(C语言):// Kruskal 最小生成树算法#include <stdio.h>#include <stdlib.h>#include <string.h>// 带有权重的边struct Edge{int src, dest, weig;};// 无向图struct Graph{// V-> 顶点个数, E->边的个数int V, E;// 由于是无向图,从 src 到 dest的边,同时也是 dest到src的边,按一条边计算struct Edge* edge;};//构建一个V个顶点 E条边的图struct Graph* createGraph(int V, int E){struct Graph* graph = (struct Graph*) malloc( sizeof(struct Graph) );graph->V = V;graph->E = E;graph->edge = (struct Edge*) malloc( graph->E * sizeof( struct Edge ) ); return graph;}//并查集的结构体struct subset{int parent;int rank;};// 使用路径压缩查找元素iint find(struct subset subsets[], int i){if (subsets[i].parent != i)subsets[i].parent = find(subsets, subsets[i].parent);return subsets[i].parent;}// 按秩合并 x,yvoid Union(struct subset subsets[], int x, int y){int xroot = find(subsets, x);int yroot = find(subsets, y);if (subsets[xroot].rank < subsets[yroot].rank)subsets[xroot].parent = yroot;else if (subsets[xroot].rank > subsets[yroot].rank)subsets[yroot].parent = xroot;else{subsets[yroot].parent = xroot;subsets[xroot].rank++;}}// 很据权重比较两条边int myComp(const void* a, const void* b){struct Edge* a1 = (struct Edge*)a;struct Edge* b1 = (struct Edge*)b;return a1->weig > b1->weig;}// Kruskal 算法void KruskalMST(struct Graph* graph){int V = graph->V;struct Edge result[V]; //存储结果int e = 0; //result[] 的indexint i = 0; // 已排序的边的 index//第一步排序qsort(graph->edge, graph->E, sizeof(graph->edge[0]), myComp);// 为并查集分配内存struct subset *subsets =(struct subset*) malloc( V * sizeof(struct subset) );// 初始化并查集for (int v = 0; v < V; ++v){subsets[v].parent = v;subsets[v].rank = 0;}// 边的数量到V-1结束while (e < V - 1){// Step 2: 先选最小权重的边struct Edge next_edge = graph->edge[i++];int x = find(subsets, next_edge.src);int y = find(subsets, next_edge.dest);// 如果此边不会引起环if (x != y){result[e++] = next_edge;Union(subsets, x, y);}// 否则丢弃,继续}// 打印result[]printf("Following are the edges in the constructed MST\n");for (i = 0; i < e; ++i)printf("边:%d -> %d 权值: %d\n", result[i].src, result[i].dest, result[i].weig);return;}// 入口函数int main(){int V = 4; // 顶点个数int E = 5; //边的个数struct Graph* graph = createGraph(V, E);// 添加边 0-1graph->edge[0].src = 0; graph->edge[0].dest = 1; graph->edge[0].weig = 10;graph->edge[1].src = 0; graph->edge[1].dest = 2; graph->edge[1].weig = 6;graph->edge[2].src = 0; graph->edge[2].dest = 3; graph->edge[2].weig = 5;graph->edge[3].src = 1; graph->edge[3].dest = 3; graph->edge[3].weig = 15;graph->edge[4].src = 2; graph->edge[4].dest = 3; graph->edge[4].weig = 4;KruskalMST(graph);return 0;}运行结果为:五、实验体会理论补充:什么是最小生成树?生成树是相对图来说的,一个图的生成树是一个树并把图的所有顶点连接在一起。