算法设计与分析实验报告实验名称贪心算法实现背包问题评分实验日期年月日指导教师姓名专业班级学号一.实验要求1. 优化问题有n个输入,而它的解就由这n个输入满足某些事先给定的约束条件的某个子集组成,而把满足约束条件的子集称为该问题的可行解。
可行解一般来说是不唯一的。
那些使目标函数取极值(极大或极小)的可行解,称为最优解。
2.贪心法求优化问题算法思想:在贪心算法中采用逐步构造最优解的方法。
在每个阶段,都作出一个看上去最优的决策(在一定的标准下)。
决策一旦作出,就不可再更改。
作出贪心决策的依据称为贪心准则(greedy criterion)。
3.一般方法1)根据题意,选取一种量度标准。
2)按这种量度标准对这n个输入排序3)依次选择输入量加入部分解中。
如果当前这个输入量的加入,不满足约束条件,则不把此输入加到这部分解中。
procedure GREEDY(A,n) /*贪心法一般控制流程*///A(1:n)包含n个输入//solutions←φ //将解向量solution初始化为空/for i←1 to n dox←SELECT(A)if FEASIBLE(solution,x)then solutions←UNION(solution,x)endifrepeatreturn(solution)end GREEDY4. 实现典型的贪心算法的编程与上机实验,验证算法的时间复杂性函数。
二.实验内容1. 编程实现背包问题贪心算法。
通过具体算法理解如何通过局部最优实现全局最优,并验证算法的时间复杂性。
2.输入5个的图的邻接矩阵,程序加入统计prim算法访问图的节点数和边数的语句。
3.将统计数与复杂性函数所计算比较次数比较,用表格列出比较结果,给出文字分析。
三.程序算法1.背包问题的贪心算法procedure KNAPSACK(P,W,M,X,n)//P(1:n)和W(1;n)分别含有按P(i)/W(i)≥P(i+1)/W(i+1)排序的n件物品的效益值和重量。
M是背包的容量大小,而x(1:n)是解向量real P(1:n),W(1:n),X(1:n),M,cu;integer i,n;X←0 //将解向量初始化为零cu←M //cu是背包剩余容量for i←1 to n doif W(i)>cu then exit endifX(i) ←1cu←cu-W(i)repeatif i≤n then X(i) ←cu/ W(i)endifend GREEDY-KNAPSACKprocedure prim(G,)status←“unseen” // T为空status[1]←“tree node” // 将1放入Tfor each edge(1,w) dostatus[w]←“fringe” // 找到T的邻接点dad[w] ←1; //w通过1与T建立联系dist[w] ←weight(1,w) //w到T的距离repeatwhile status[t]≠“tree node” dopick a fringe u with min dist[w] // 选取到T最近的节点status[u]←“tree node”for each edge(u,w) do修改w和T的关系repeatrepeat2.Prim算法PrimMST(G,T,r){//求图G的以r为根的MST,结果放在T=(U,TE)中InitCandidateSet(…);//初始化:设置初始的轻边候选集,并置T=({r},¢) for(k=0;k<n-1;k++){ //求T的n-1条树边(u,v)=SelectLiShtEdge(…);//选取轻边(u,v);T←T∪{(u,v)};//扩充T,即(u,v)涂红加入TE,蓝点v并人红点集UModifyCandidateSet(…); //根据新红点v调整候选轻边集}四.程序代码1.背包问题贪心算法#include <iostream.h>struct goodinfo{float p; //物品效益float w; //物品重量float X; //物品该放的数量int flag; //物品编号};//物品信息结构体void Insertionsort(goodinfo goods[],int n){int j,i;for(j=2;j<=n;j++){goods[0]=goods[j];i=j-1;while (goods[0].p>goods[i].p){goods[i+1]=goods[i];i--;}goods[i+1]=goods[0];}}//按物品效益,重量比值做升序排列void bag(goodinfo goods[],float M,int n){float cu;int i,j;for(i=1;i<=n;i++)goods[i].X=0;cu=M; //背包剩余容量for(i=1;i<n;i++){if(goods[i].w>cu)//当该物品重量大与剩余容量跳出break;goods[i].X=1;cu=cu-goods[i].w;//确定背包新的剩余容量}if(i<=n)goods[i].X=cu/goods[i].w;//该物品所要放的量for(j=2;j<=n;j++){goods[0]=goods[j];i=j-1;while (goods[0].flag<goods[i].flag){goods[i+1]=goods[i];i--;}goods[i+1]=goods[0];}cout<<"最优解为:"<<endl;for(i=1;i<=n;i++){cout<<"第"<<i<<"件物品要放:";cout<<goods[i].X<<endl;}}void main(){cout<<"|--------运用贪心法解背包问题---------|"<<endl; cout<<"|-------------------------------------|"<<endl; int j;int n;float M;goodinfo *goods;//定义一个指针while(j){cout<<"请输入物品的总数量:";cin>>n;goods=new struct goodinfo [n+1];//cout<<"请输入背包的最大容量:";cin>>M;cout<<endl;int i;for(i=1;i<=n;i++){ goods[i].flag=i;cout<<"请输入第"<<i<<"件物品的重量:";cin>>goods[i].w;cout<<"请输入第"<<i<<"件物品的效益:";cin>>goods[i].p;goods[i].p=goods[i].p/goods[i].w;//得出物品的效益,重量比 cout<<endl;}Insertionsort(goods,n);bag(goods,M,n);cout<<"press <1> to run agian"<<endl;cout<<"press <0> to exit"<<endl;cin>>j;}}2.Prim算法#include <stdio.h>#include <stdlib.h>#include <iostream.h>#define INFINITY INT_MAX#define MAX_VERTEX_NUM 20typedef int VRType;typedef int InfoType;typedef char VerTexType;typedef struct ArcCell{VRType adj;InfoType *info;}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];typedef struct{VerTexType vexs[MAX_VERTEX_NUM];AdjMatrix arcs;int vexnum, arcnum;}MGraph;typedef struct{VerTexType adjvex;VRType lowcost;}closedge[MAX_VERTEX_NUM];void CreateGraph(MGraph &G);void MiniSpanTree_PRIM(MGraph G, VerTexType u); int LocateVex(MGraph G, VerTexType u);int minimum(closedge close);void main( void ){int i, j;MGraph G;CreateGraph(G);for(i = 0; i < G.vexnum; i++){for(j = 0; j < G.vexnum; j++){cout<<G.arcs[i][j].adj;cout<<" ";}cout<<endl;}MiniSpanTree_PRIM(G, 'a');}void CreateGraph(MGraph &G){int weigh;int i, j = 0, k = 0;char hand, tide;cout<<"input the number for vexnum and arcnum:";cin>>G.vexnum>>G.arcnum;for(i = 0; i < G.vexnum; i++){for(j = 0; j < G.vexnum; j++)G.arcs[i][j].adj = 88;}cout<<endl;cout<<"input"<<G.vexnum<<"char for vexs:";for(i=0; i < G.vexnum; i++)cin>>G.vexs[i];cout<<endl;cout<<"input"<<G.arcnum<<"arc(char,char,weigh):"<<endl; j = 0;k = 0;for(i=0; i < G.arcnum; i++){cout<<i<<":";cin>>hand;cin>>tide;cin>>weigh;while (hand != G.vexs[j])j++;while (tide != G.vexs[k])k++;G.arcs[j][k].adj = weigh;G.arcs[k][j].adj = weigh;j = 0;k = 0;cout<<endl;}}void MiniSpanTree_PRIM(MGraph G,VerTexType u){int i, j, k = 0;closedge close;k = LocateVex ( G, u );for ( j = 0; j < G.vexnum; j++ ){if (j != k){close[j].adjvex = G.vexs[k];close[j].lowcost = G.arcs[k][j].adj;}}close[j].lowcost = 88;close[j].adjvex = '\0';close[k].lowcost = 0;close[k].adjvex = u;for (i = 1; i < G.vexnum; i++){k = minimum(close);cout<<close[k].adjvex;cout<<"---->";cout<<G.vexs[k]<<" ";cout<<close[k].lowcost<<endl;close[k].lowcost = 0;for (j=0; j<G.vexnum; j++){if (G.arcs[k][j].adj < close[j].lowcost) {close[j].adjvex = G.vexs[k];close[j].lowcost = G.arcs[k][j].adj;}}}}int LocateVex(MGraph G, VerTexType u){int k = 0;while(G.vexs[k++] == u)return k-1;return 0;}int minimum(closedge close){int j1=0, client = 88, j2;while(close[j1].adjvex != '\0'){if (client > close[j1].lowcost && close[j1].lowcost != 0) {client = close[j1].lowcost;j2 = j1;}j1++;}return j2;}六.实验结果1. 背包问题贪心算法2. Prim算法。