第4章 贪心算法实验指导
贪心算法实验报告算法实验贪心法实验报告

贪心算法实验报告算法实验贪心法实验报告西安邮电大学(计算机学院)课内实验报告实验名称:贪心算法专业名称:班级:学生姓名:学号(8指导教师:实验日期:一. 实验目的及实验环境1.练习掌握最有分解问题的规划设计与实现;2.熟练掌握递归算法的设计及应用,怎样才能使算法的空间复杂度和时间复杂度最低;基于Linux系统下的ubuntu或其他的编辑器二. 实验内容1. 设n是一个正整数,现在要求将n分解为若干互不相同的自然数的和,且使这些自然数的乘积最大三.方案设计1.先将这个数分解成以2开始的连续的若干因子,它们的和加起来是n,将此数在后项优先的方式下均匀地分给前面各项。
保证正整数所分解出的因子之差的绝对值最小,即| a – b |最小,可以保证分解乘积越大。
四.测试数据及运行结果1.正常测试数据(3组)及运行结果;A.2.非正常测试数据(2组)及运行结果A.B.五.总结1.实验过程中遇到的问题及解决办法;在实验过程中错误不断地出现,我认真地查阅书籍,研究课本上例题,并且在同学的帮助下纠正了自己的错误,得出了正确的结果。
2.对设计及调试过程的心得体会。
在程序的运行与调试过程中出现了很多错误,但是通过自己复习课本知识、查询资料等,修改后得出了正确的结果。
而且我觉得自己一定要敢于尝试,即使没有结果但是勇于实践就会有意想不到的收获。
所以在以后的学习中我觉得我们一定要集中精力、端正自己态度,提高自己的成绩。
当然我也认识到了自己的薄弱之处,因此我一定争取做的能让自己满意,做的更好。
六.附录:源代码(电子版)#include#includevoid open_file(int n){FILE *fp;if((fp=fopen(“input.txt”,”wt”))==NULL) {printf(“the file write failed.\n”);exit(1);}fprintf(fp,”%2d\n”,n);fclose(fp);}void save_file(int sum){FILE *fp;if((f p=fopen(“output.txt”,”wt”))==NULL) {printf(“ the file save failed!.\n”);exit(1);}fprintf(fp,”%2d\n”,sum);fclose(fp);if((fp=fopen(“output.txt”,”r”))==NULL) {printf(“save file failed!\n”);exit(1);}fscanf(fp,”%2d”,&sum);printf(“\n鏈€澶х?d\n”,sum);fclose(fp);}int MAX(int n){int i=2,j=0,data[n],sum=0,max=1; int lenth; while(sum+i{sum+=i;data[j]=i;i++;j++;}lenth=j;i=n-sum;while(i>0){if(j{data[j+i]+=1;i--;j--;}else{data[j-1]+=1;i--;j--;}}for(i=0;imax*=data[i];return max;}int main(){int n,max;srand((unsigned)time(NULL)); n=rand()%100; open_file(n);printf(“ 杩欎釜鏁版槸%d:\n”,n); max=MAX(n); save_file(max);return 0; }百度搜索“就爱阅读”,专业资料,生活学习,尽在就爱阅读网,您的在线图书馆。
贪心算法实验(求解背包问题)

算法分析与设计实验报告第四次实验
}
}
输入较小的结果:
测试结
果
输入较大的结果:
附录:
完整代码(贪心法)
;
cout<<endl;
cout<<"待装物品的价值为:"<<endl;
for (i=0;i<n;i++)
cin>>item[i].v;
cout<<endl;
erval=item[i].v/item[i].w;
clock_t start,end,over; ;
实验心
得
首先这个实验,需要注意的点是背包问题与0-1背包不同,物品可以部分的放入背包中,所以思路也不一样,首先就是将物品按照单位质量价值排序,只这一点就有一点难度。
难度在于要是排序后物品的编号就会发生改变,输出的就不是之前的编号的物品,导致错误,后来发现如果为每一个物品保存一个副本,然后将它们的编号进行对比,就可以进行正确的输出了。
其中这个实验
让我学到了两点:一是结构体的使用,之前一直没有怎么用过,现在才发现自己其实不会用;二十对于库函数sort 函数的使用。
感觉每一次实验都有学到东西,很开心。
实验得
分 助教签名
sort(item,item+n,comparison); >c)
break;
tem[i]=1;
c-=item[i].w;
}
if(i<n) ;
for(i=0;i<n;i++) ==tmp[j])
x[j]=tem[i];
}
}
}。
贪心算法 实验报告

贪心算法实验报告贪心算法实验报告引言:贪心算法是一种常用的算法设计策略,它通常用于求解最优化问题。
贪心算法的核心思想是在每一步选择中都选择当前最优的解,从而希望最终能够得到全局最优解。
本实验旨在通过实际案例的研究,探索贪心算法的应用和效果。
一、贪心算法的基本原理贪心算法的基本原理是每一步都选择当前最优解,而不考虑整体的最优解。
这种贪婪的选择策略通常是基于局部最优性的假设,即当前的选择对于后续步骤的选择没有影响。
贪心算法的优点是简单高效,但也存在一定的局限性。
二、实验案例:零钱兑换问题在本实验中,我们以零钱兑换问题为例,来说明贪心算法的应用。
问题描述:假设有不同面值的硬币,如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个。
算法设计与分析:第4章 贪心法

& 7
i 1 2 3 4 5 6 7 8 9 10 11 si 1 3 0 5 3 5 6 8 8 2 12 fi 4 5 6 7 8 9 10 11 12 13 14
3 1 0 1 Pa2ge 263 4
4 4
7 6
• +HJ-solution
– D5+>&S?F#6+
• '9J-select
– G CAKG !E – 30':4$F#+ – ")28J-
• +HJ-feasible
– D5+>& ':? K,+>& I;?.7=@%
贪心法的一般过程
7 (*)906 42:
– 6 "#3 – -,!*);&'4"# – !. ;&6 +/ ( –
/ (#
8 "# ( 5%( ()
– (#$1 (#
4.1.4 贪心法的求解过程
三个步骤
3
•
建立模型(问题抽象化)
ō 冇㩀㩂⇗
%
! &"'" = )
(1. 3)
"#$
0 ≤ '" ≤ 1, 1 ≤ . ≤ /
ō 䧏㫨ⓞ㡑
%
max ! 8"'"
(1. 9)
"#$
ō 厭◦棏歹㈳冴ℛ⻜㕟⃡ℋ䇂悔冇㩀㩂⇗ㇰ猾ㅗ≠䧏㫨ⓞ
㡑ㇰ抟┑㧡Ⰸ䥥峄⛲撰 : = ('1, '2, … , '/)
QPNX:E
算法实验报告贪心

一、实验背景贪心算法是一种在每一步选择中都采取当前状态下最好或最优的选择,从而希望导致结果是全局最好或最优的算法策略。
贪心算法并不保证能获得最优解,但往往能获得较好的近似解。
在许多实际应用中,贪心算法因其简单、高效的特点而被广泛应用。
本实验旨在通过编写贪心算法程序,解决经典的最小生成树问题,并分析贪心算法的优缺点。
二、实验目的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算法:从任意一个顶点开始,逐步添加边,直到所有顶点都被包含在生成树中。
贪心算法

贪心算法实验报告一.实验目的:1.加深对贪心算法思想的理解,实现背包问题、活动安排问题的求解算法;2.通过本次实验掌握将算法转换为上机操作;3.加深对动态规划思想的理解,并利用其解决生活中的问题。
二.实验内容:1.编写算法:实现背包问题、活动安排问题的求解;2.将输出数据保存到文件之中,包括运行时间和运行结果;3.对实验结果进行分析。
三.实验操作:1.背包问题:给定一个容器,即背包,有若干的物品,有重量和价值两个属性,要将背包填满并且价值最大。
共有三种方式,以重量优先、价值优先和单位价值优先对背包进行填充,对三种结果进行比较分析,得到最优解。
代码实现:class knapsack{//背包属性public:float weight,value,unitValue;knapsack();void QsortWeight(knapsack bag[],int low,int high);void QsortValue(knapsack bag[],int low,int high);void QsortUnitValue(knapsack bag[],int low,int high); void GreedyKnapsack(knapsack bag[],float volume,int amount);};void knapsack::GreedyKnapsack(knapsack bag[],floatvolume,int amount){//贪心解决背包问题float surplusCapacity=volume,totalValue=0;int j=0;float* select=new float[amount];for(int i=0;i<amount;i++) select[i]=0;for(j=0;j<amount;j++){if(bag[j].weight>surplusCapacity) break;select[j]=1.0;surplusCapacity-=bag[j].weight;totalValue+=bag[j].value;cout<<bag[j].weight<<" "<<bag[j].value<<""<<bag[j].unitValue<<endl;outFile<<bag[j].weight<<" "<<bag[j].value<<""<<bag[j].unitValue<<"\n";}if(j<amount) select[j]=surplusCapacity/bag[j].weight;totalValue+=bag[j].value*select[j];outFile<<bag[j].weight<<" "<<bag[j].value<<""<<bag[j].unitValue<<"\n"<<"总价值为:"<<totalValue<<"\n";cout<<bag[j].weight<<" "<<bag[j].value<<""<<bag[j].unitValue<<endl;cout<<"总价值为:"<<totalValue<<endl;}2.活动安排:在一天之中最大限度得安排活动,给定一系列活动的开始时间和结束时间,对结束时间按照非递减顺序排列,判断当前活动的开始时最后时间与上个活动的结束时间是否有冲突,如果没有,将当前活动放入活动安排表中,直到判断到最后一个活动或者结束时间到头为止。
贪心算法_实验报告

贪心算法_实验报告一、设计分析●问题描述:键盘输入一个高精度的正整数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);三、测试用例四、实验总结加深了对贪心算法的理解与运用。
所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。
这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。
动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。
实验四 贪心算法

实验四贪心算法一、实验目的进一步理解贪心算法的基本思想,学会根据具体问题设计贪心选择策略,会使用贪心算法解决一些实际问题。
二、实验要求1、上机前的准备工作根据实验内容中所给题目,利用所学贪心算法的基本设计思想设计算法并编写好上机程序,以提高上机效率;2、独立上机,输入、调试所编程序;3、上机结束后,写出实验报告。
4、上机时间:2学时三、实验内容1、4-1 会场安排问题#include<iostream>using namespace std;const int MAX=100;struct sport{int start;//开始时间int end;//结束时间};int m[MAX];void sort(struct sport t[],int n)// 由小到大排序{int i,j;for(i=1;i<n;i++)for(j=1;j<n-i+1;j++)if(t[j].start>t[j+1].start){struct sport temp;temp=t[j];t[j]=t[j+1];t[j+1]=temp;}}void main(){int max=1,count=1,n;cout<<"请输入活动的个数:";cin>>n;sport t[MAX];for(int k=1;k<=n;k++){cout<<"请输入第"<<k<<"个活动的开始时间和结束时间:";cin>>t[k].start;cin>>t[k].end;}m[0]=t[1].end;sort(t,n);for(int i=2;i<=n;i++){int j=0;while(j<max&&t[i].start<m[j]){j++;}m[j]=t[i].end;count=j+1;if(count>max)max=count;}cout<<"活动场所共需个数:"<<max<<endl;}运行结果:2、4-2 最优合并问题#include <iostream>using namespace std;const int MAX=100;void sort(int r[],int n){int j;for(int i=2;i<=n;i++){r[0]=r[i];j=i-1;while(r[0]<r[j]){r[j+1]=r[j];j=j-1;}r[j+1]=r[0];}}int max(int r[],int n){int sum=0;for(int i=n;i>1;i--){sum+=r[i]+r[i-1]-1;r[i-1]=r[i]+r[i-1];}return sum;}int min(int r[],int n){int sum=0;for(int i=1;i<n;i++){sum+=r[i]+r[i+1]-1;r[i+1]=r[i]+r[i+1];}return sum;}void main(){int n,a[MAX],b[MAX];cout<<"请输入序列的个数:";cin>>n;cout<<"请输入各个序列的长度:"<<endl;for(int i=1;i<=n;i++)cin>>a[i];sort(a,n);for(int j=1;j<=n;j++)b[j]=a[j];cout<<"最多比较次数:"<<max(a,n)<<endl;cout<<"最少比较次数:"<<min(b,n)<<endl; }运行结果:3、数列极差问题在黑板上写了N个正整数组成的一个数列,进行如下操作:每一次擦去其中的两个数a和b,然后在数列中加入一个数a×b+3,如此下去直至黑板上剩下一个数,在所有按这种操作方式最后得到的数中,最大的记作max,最小的记作min,则该数列的极差定义为M=max-min。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第4章贪心算法
实验4.1 贪心算法的实现与时间复杂度测试
1. 实验目的
编程实现经典的贪心算法,理解贪心算法设计的基本思想、程序实现的相关技巧,加深对贪心算法设计与分析思想的理解。
通过程序的执行时间测试结果,与理论上的时间复杂度结论进行对比、分析和验证。
2. 原理解析
贪心算法的基本思想
贪心算法求解优化问题的基本思想是:采用逐步构造最优解的方法。
在每个阶段,都做出一个当前最优的决策(在一定的标准下)。
决策一旦做出,就不可再更改(做出贪心决策的依据称为贪心准则)。
贪心算法的一般步骤如下:
(1) 根据拟解决问题选取一种贪心准则;
(2) 按贪心准则标准对n个候选输入排序(以这一方法为代表,仍可基于堆来存储候选);
(3) 依次选择输入量加入部分解中:如果当前这个输入量的加入,不满足约束条件,则不把此输入加到这部分解中。
贪心算法的基本设计范式如下:
Greedy(A,n)
A: include n inputs
Solution=Ф
for i=1 to n do
x=Select(A)
if Feasible(solution,x) then
solution=Union(solution,x)
end if
end for
return solution
测试算法
背包问题是使用贪心算法求解的代表问题,算法如下:
KnapsackGreedy(p,w,m,x,n)
//v[1..n]和w[1..n]分别含有按vi/wi v(i+1)/v(i+1)排序的n 件物品的价值和重量。
M是背包的容量大小,而x[1..n]是解向量// for i=1 to n do
xi=0 //将解向量初始化为零//
end for
cu=m //cu是背包剩余容量//
for i=1 to n do
if wi>cu then
exit
end if
xi=1
cu=cu-wi
repeat
if i≤n then
xi=cu/wi
end if
算法的时间复杂度取决于对v i/w i排序的时间复杂度,例如,若选择MergeSort 排序算法,则以上算法的时间复杂度为O(n log n)。
3. 实验内容
(1)编程实现以上求解背包问题的贪心算法,并通过手动设置、生成随机数获得实验数据。
记录随着输入规模增加算法的执行时间,分析并以图形方式展现增长率;测试、验证、对比算法的时间复杂度。
(2)利用贪心算法思想,设计实现单源最短路径问题的算法,并编程实现。
4. 实验步骤和要求
实验内容(1)步骤:
(1) 编程实现以上KnapsackGreedy算法,并进行测试,保证程序正确无误。
其中,分别在程序开始和结束处设置记录系统当前时间的变量、用于计算程序执行的时间(以毫秒(ms)作为时间的计数单位)。
(2) 设定一个m值(背包容量),测试随着n增加、程序执行时间增加的趋势。
分别使用实验1中的随机数生成算法生成n个随机数作为n个物品的重量,再生成n个随机数作为n个物品的价值(n=10, 20, 40, 100, 200, 400, 800, 2000)。
记录随着n增加程序的执行时间,并使用MS Excel图表绘制工具生成程序执行时间的对比曲线图。
(3) 与理论上的时间复杂度结论进行对比分析,完成实验报告。
实验内容(2)步骤:
(1)分析该问题的贪心选择性质;
(2)分析该问题的最优子结构性质;
(3)算法的设计与实现;。