贪心法求解01背包问题
贪心算法-01背包问题
![贪心算法-01背包问题](https://img.taocdn.com/s3/m/18ae521ff08583d049649b6648d7c1c708a10bf6.png)
贪⼼算法-01背包问题1、问题描述:给定n种物品和⼀背包。
物品i的重量是wi,其价值为vi,背包的容量为C。
问:应如何选择装⼊背包的物品,使得装⼊背包中物品的总价值最⼤?形式化描述:给定c >0, wi >0, vi >0 , 1≤i≤n.要求找⼀n元向量(x1,x2,…,xn,), xi∈{0,1}, ∋ ∑ wi xi≤c,且∑ vi xi达最⼤.即⼀个特殊的整数规划问题。
2、最优性原理:设(y1,y2,…,yn)是 (3.4.1)的⼀个最优解.则(y2,…,yn)是下⾯相应⼦问题的⼀个最优解:证明:使⽤反证法。
若不然,设(z2,z3,…,zn)是上述⼦问题的⼀个最优解,⽽(y2,y3,…,yn)不是它的最优解。
显然有∑vizi > ∑viyi (i=2,…,n)且 w1y1+ ∑wizi<= c因此 v1y1+ ∑vizi (i=2,…,n) > ∑ viyi, (i=1,…,n)说明(y1,z2, z3,…,zn)是(3.4.1)0-1背包问题的⼀个更优解,导出(y1,y2,…,yn)不是背包问题的最优解,⽭盾。
3、递推关系:设所给0-1背包问题的⼦问题的最优值为m(i,j),即m(i,j)是背包容量为j,可选择物品为i,i+1,…,n时0-1背包问题的最优值。
由0-1背包问题的最优⼦结构性质,可以建⽴计算m(i,j)的递归式:注:(3.4.3)式此时背包容量为j,可选择物品为i。
此时在对xi作出决策之后,问题处于两种状态之⼀:(1)背包剩余容量是j,没产⽣任何效益;(2)剩余容量j-wi,效益值增长了vi ;使⽤递归C++代码如下:#include<iostream>using namespace std;const int N=3;const int W=50;int weights[N+1]={0,10,20,30};int values[N+1]={0,60,100,120};int V[N+1][W+1]={0};int knapsack(int i,int j){int value;if(V[i][j]<0){if(j<weights[i]){value=knapsack(i-1,j);}else{value=max(knapsack(i-1,j),values[i]+knapsack(i-1,j-weights[i]));}V[i][j]=value;}return V[i][j];}int main(){int i,j;for(i=1;i<=N;i++)for(j=1;j<=W;j++)V[i][j]=-1;cout<<knapsack(3,50)<<endl;cout<<endl;}不使⽤递归的C++代码:简单⼀点的修改//3d10-1 动态规划背包问题#include <iostream>using namespace std;const int N = 4;void Knapsack(int v[],int w[],int c,int n,int m[][10]);void Traceback(int m[][10],int w[],int c,int n,int x[]);int main(){int c=8;int v[]={0,2,1,4,3},w[]={0,1,4,2,3};//下标从1开始int x[N+1];int m[10][10];cout<<"待装物品重量分别为:"<<endl;for(int i=1; i<=N; i++){cout<<w[i]<<" ";}cout<<endl;cout<<"待装物品价值分别为:"<<endl;for(int i=1; i<=N; i++){cout<<v[i]<<" ";}cout<<endl;Knapsack(v,w,c,N,m);cout<<"背包能装的最⼤价值为:"<<m[1][c]<<endl;Traceback(m,w,c,N,x);cout<<"背包装下的物品编号为:"<<endl;for(int i=1; i<=N; i++){if(x[i]==1){cout<<i<<" ";}}cout<<endl;return 0;}void Knapsack(int v[],int w[],int c,int n,int m[][10]){int jMax = min(w[n]-1,c);//背包剩余容量上限范围[0~w[n]-1] for(int j=0; j<=jMax;j++){m[n][j]=0;}for(int j=w[n]; j<=c; j++)//限制范围[w[n]~c]{m[n][j] = v[n];}for(int i=n-1; i>1; i--){jMax = min(w[i]-1,c);for(int j=0; j<=jMax; j++)//背包不同剩余容量j<=jMax<c{m[i][j] = m[i+1][j];//没产⽣任何效益}for(int j=w[i]; j<=c; j++) //背包不同剩余容量j-wi >c{m[i][j] = max(m[i+1][j],m[i+1][j-w[i]]+v[i]);//效益值增长vi }}m[1][c] = m[2][c];if(c>=w[1]){m[1][c] = max(m[1][c],m[2][c-w[1]]+v[1]);}}//x[]数组存储对应物品0-1向量,0不装⼊背包,1表⽰装⼊背包void Traceback(int m[][10],int w[],int c,int n,int x[]){for(int i=1; i<n; i++){if(m[i][c] == m[i+1][c]){x[i]=0;}else{x[i]=1;c-=w[i];}}x[n]=(m[n][c])?1:0;}运⾏结果:算法执⾏过程对m[][]填表及Traceback回溯过程如图所⽰:从m(i,j)的递归式容易看出,算法Knapsack需要O(nc)计算时间; Traceback需O(n)计算时间;算法总体需要O(nc)计算时间。
背包问题解析(一)-贪心算法
![背包问题解析(一)-贪心算法](https://img.taocdn.com/s3/m/19e35e1217fc700abb68a98271fe910ef12daebb.png)
背包问题解析(⼀)-贪⼼算法⼀、题⽬:有N件物品和⼀个容量为V的背包。
第i件物品的重量是w[i],价值是v[i]。
求解将哪些物品装⼊背包可使这些物品的重量总和不超过背包容量,且价值总和最⼤。
⼆、解决思路:本题刚开始的解题的时候,想采取贪⼼算法来解决,也就是将放⼊的物品的性价⽐按照从⾼到低进⾏排序,然后优先放优先级⾼的,其次优先级低的。
三、代码实现(python)1# 重量w=[5,4,3,2]2# 价值v=[6,5,4,3]3 b=[]4 m=int(input("请输⼊背包的最⼤重量:"))5 n=int(input("请输⼊商品的数量:"))6for i in range(n):7 a=input("请分别输⼊重量和价值,以空格隔开:")8 a=a.split("")9for i in range(len(a)):10 a[i]=int(a[i])11 b.append(a)12print("加载初始化:",b)13for i in range(len(b)):14for j in range(i+1,len(b)):15if b[i][1]/b[i][0]<b[j][1]/b[j][0]:16 b[i],b[j]=b[j],b[i]17print("性价⽐排序:",b)18 v=019 c=[]20for i in range(len(b)):21if m-b[i][0]>0:22 m=m-b[i][0]23 c.append(b[i])24 v+=b[i][1]25print("放⼊背包:",c)26print("最⼤价值为:",v)打印结果:四、算法分析:贪⼼选择是指所求问题的整体最优解可以通过⼀系列局部最优的选择,即贪⼼选择来达到。
贪心算法实验(求解背包问题)
![贪心算法实验(求解背包问题)](https://img.taocdn.com/s3/m/9b3e9470e2bd960591c67735.png)
算法分析与设计实验报告第四次实验
}
}
输入较小的结果:
测试结
果
输入较大的结果:
附录:
完整代码(贪心法)
;
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];
}
}
}。
01背包贪心算法
![01背包贪心算法](https://img.taocdn.com/s3/m/bddf172c2af90242a895e5d6.png)
0—1背包问题一、实验目的学习掌贪心算法法思想。
二、实验内容用分支限定法求解0—1背包问题,并输出问题的最优解。
0—1背包问题描述如下:给定n种物品和一背包。
物品i的重量是Wi,其价值为Vi,背包的容量是c,问应如何选择装入背包中的物品,使得装入背包中物品的总价值最大。
三、实验条件Jdk1.5以上四、需求分析对于给定n种物品和一背包。
在容量最大值固定的情况下,要求装入的物品价值最大化。
五、基本思想:总是对当前的问题作最好的选择,也就是局部寻优。
最后得到整体最优。
总是选择单位价值最高的物品六、详细设计package sunfa;/**** @author Administrator*/import java.util.*;public class Greedy_Algorithm {static Element dd[];static int CurrentV ;static int CurrentC;static StringBuffer stb= new StringBuffer();public static int knapasck(int c, int[] w, int[] v, int[] x) {int n = v.length;Element d [] = new Element[n];for(int i = 0 ;i< n; i++){d[i]=new Element(w[i],v[i],i+1);}//按单位重量价值升序排序Arrays.sort(d);dd =d;/*for(int i = 0; i<d.length ;i++){System.out.println("重量" +d[i].ww+ "单位价值"+d[i].wv);}*/int i = 0;int MaxV2 = 0;for(i=0;i<n;i++)x[i] = 0;for(i=0;i<n;i++){if(d[i].ww>c)break;else{x[i] = d[i].tag; //x【】中存的是原元素的序号MaxV2 = MaxV2+d[i].value;c = c -d[i].ww;CurrentC =c ;stb.append("选择第" + d[i].tag + "个当前价值:"+MaxV2+ "剩余容量:"+c+"\n");}}return MaxV2;}}class Element implements Comparable{int ww; //物品重量int value; //物品价值double wv;//物品单位重量的价值int tag;//物品的标志是第一个物品public Element(int w ,int vv ,int tag){this.tag = tag;this.ww = w;this.value = vv;wv = (double)vv/w;}//对象比较的方法public int compareTo(Object x){Element temp = (Element)x;double rate = (double)ww/value;double temprate = (double)temp.ww/temp.value;if(rate<temprate)return -1;if(rate==temprate)return 0;elsereturn 1;}}运行结果(用列一)用列二上述结果显示:贪心算法不是总是最优的.动态规划与贪心算法比较;动态规划法又和贪婪算法有些一样,在动态规划中,可将一个问题的解决方案视为一系列决策的结果。
贪心法求解01背包问题
![贪心法求解01背包问题](https://img.taocdn.com/s3/m/2a1e0c8a84868762caaed56c.png)
贪心法的关键是度量标准,这个程序的度量标准有三个占用空间最小物品效益最大物品效益/占用空间最大程序实现如下:至于文件的操作不加论述。
#include <stdio.h>#include <stdlib.h>typedef struct{char name[10];int weight;int price;}Project;Project *Input(Project *wp,int TotalNum,int TotalWeight) {int i,j,Way,GoBack,RealWeight,RealPrice,TotalPrice;Project temp;do{printf("请选择:\n");printf(" 1.空间最优\n");printf(" 2.价格最优\n");printf(" 3.价格空间比最优\n");scanf("%d",&Way);switch(Way){case 1:for(i=0;i<TotalNum;i++)for(j=0;j<TotalNum-i-1;j++){if(wp[j].weight>wp[j+1].weight){temp=wp[j];wp[j]=wp[j+1];wp[j+1]=temp;}}break;case 2:for(i=0;i<TotalNum;i++)for(j=0;j<TotalNum-i-1;j++){if(wp[j].price<wp[j+1].price){temp=wp[j];wp[j]=wp[j+1];wp[j+1]=temp;}}break;case 3:for(i=0;i<TotalNum;i++)for(j=0;j<TotalNum-i-1;j++){if((float)wp[j].price/(float)wp[j].weight<(float)wp[j+1].price/(float)wp[j+1].weight){temp=wp[j];wp[j]=wp[j+1];wp[j+1]=temp;}}break;default:{printf("输入错误!\n");exit(1);}}i=0;RealWeight=wp[0].weight;TotalPrice=wp[0].price;printf("被装入背包的物品是:\n(物品名价格重量)\n");while(RealWeight<TotalWeight&&i<TotalNum){printf("%s %d %d\n",wp[i].name,wp[i].price,wp[i].weight);i++;RealWeight+=wp[i].weight;TotalPrice+=wp[i].price;}RealWeight-=wp[i].weight;TotalPrice-=wp[i].price;printf("求解结束!背包所装物品总重量:%d,总价值:%d\n",RealWeight,TotalPrice);printf("退出本次测试请按0!\n");scanf("%d",&GoBack);}while(GoBack!=0);return wp;}void main(){int InputWay,TotalNum,i,TotalWeight,RealWeight,Goon,TotalPrice;Project *Array;FILE *fp;do{printf("请选择数据录入方式!\n");printf(" 1.文件读入\n");printf(" 2.键盘输入\n");scanf("%d",&InputWay);switch(InputWay){case 1:printf("请输入背包最大容量:");scanf("%d",&TotalWeight);fp=fopen("data.txt","r");fscanf(fp,"%d\n",&TotalNum);if((Array=(Project*)malloc(TotalNum*sizeof(Project)))==NULL){printf("内存已满,申请空间失败!\n");exit(1);}else{for(i=0;i<TotalNum;i++){fscanf(fp,"%s %d %d\n",&Array[i].name,&Array[i].price,&Array[i].weight);}}fclose(fp);Array=Input(Array,TotalNum,TotalWeight);break;case 2:printf("请输入物品数量及背包容量\n");scanf("%d%d",&TotalNum,&TotalWeight);if((Array=(Project*)malloc(TotalNum*sizeof(Project)))==NULL){printf("内存已满,申请空间失败!\n");exit(1);}else{printf("请输入:物品名价格重量\n");for(i=0;i<TotalNum;i++)scanf("%s%d%d",&Array[i].name,&Array[i].price,&Array[i].weight);}Array=Input(Array,TotalNum,TotalWeight);break;default:{printf("输入错误!\n");exit(1);}}printf("继续其他数据测试请按1\n");scanf("%d",&Goon);}while(Goon==1);delete Array;}。
用蛮力法、动态规划法和贪心法求解0 1背包问题
![用蛮力法、动态规划法和贪心法求解0 1背包问题](https://img.taocdn.com/s3/m/aae6ec395acfa1c7aa00ccea.png)
printf("\n");
}
}
以下要依次判断每个子集的可行性,找出可行解:
voidpanduan(inta[][4],intcw[])////判断每个子集的可行性,如果可行则计算其价值存入数组cw,不可行则存入0
{
int i,j;
int n=16;
int sw,sv;
for(i=0;i<16;i++)
用蛮力法解决0/1背包问题,需要考虑给定n个物品集合的所有子集,找出所有可能的子集(总重量不超过背包容量的子集),计算每个子集的总价值,然后在他们中找到价值最大的子集。
所以蛮力法解0/1背包问题的关键是如何求n个物品集合的所有子集,n个物品的子集有2的n次方个,用一个2的n次方行n列的数组保存生成的子集,以下是生成子集的算法:void force(int a[][4])//蛮力法产生4个物品的子集
{
int i,j;
int n=16;
int m,t;
for(i=0;i<16;i++)
{t=i;
for(j=3;j>=0;j--)
{
m=t%2;
a[i][j]=m;
t=t/2;
}
}
for(i=0;i<16;i++)//输出保存子集的二维数组
{
for(j=0;j<4;j++)
{
printf("%d",a[i][j]);
i++;
}
return maxprice;
}
#include<stdio.h>
#include<stdlib.h>
贪心法解决背包问题
![贪心法解决背包问题](https://img.taocdn.com/s3/m/b1e7b9e390c69ec3d4bb7545.png)
算法分析实验报告贪心法解决背包问题学生姓名:专业:班级:学号:指导教师:2017年6月12日目录一、实验题目 (2)二、实验目的 (2)三、实验要求 (2)四、实现过程 (3)1、实验设计: (3)2、调试分析 (5)3、运行结果: (6)4、实验总结: (6)五、参考文献 (6)一、实验题目贪心法解决背包问题二、实验目的1)以背包问题为例,掌握贪心法的基本设计策略。
2)熟练掌握各种贪心策略情况下的背包问题的算法并实现;其中:量度标准分别取:效益增量v、物品重量w、v/ w比值;3) 分析实验结果来验证理解贪心法中目标函数设计的重要性。
三、实验要求1.[问题描述]:给定n种物品和一个背包。
物品i的重量是Wi,其价值为Vi,背包的容量为C。
应如何选择装入背包的物品,使得装入背包中物品的总价值最大? 与0-1背包问题类似,所不同的是在选择物品i装入背包时,可以选择物品i的一部分,而不一定要全部装入背包,但不可以重复装入。
2.[算法]:贪心法的基本思路:从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。
当达到某算法中的某一步不能再继续前进时,算法停止。
该算法存在问题:1)不能保证求得的最后解是最佳的;2)不能用来求最大或最小解问题;3)只能求满足某些约束条件的可行解的范围。
四、实现过程1、实验设计:1.用贪心法求解背包问题的关键是如何选定贪心策略,使得按照一定的顺序选择每个物品,并尽可能的装入背包,直至背包装满。
至少有三种看似合理的贪心策略:1)按物品价值v降序装包,因为这可以尽可能快的增加背包的总价值。
但是,虽然每一步选择获得了背包价值的极大增长,但背包容量却可能消耗太快,使得装入背包得物品个数减少,从而不能保证目标函数达到最大。
2)按物品重量w升序装包,因为这可以装入尽可能多的物品,从而增加背包总价值。
但是,虽然每一步选择使背包得容量消耗得慢了,但背包价值却没能保证迅速增长,从而不能保证目标函数达到最大。
贪心算法之背包问题
![贪心算法之背包问题](https://img.taocdn.com/s3/m/6455310478563c1ec5da50e2524de518964bd3ac.png)
贪⼼算法之背包问题贪⼼算法之背包问题1.与动态规划的区别通过研究解决经典的组合优化问题,来说明⼆者的差别。
即0-1背包问题与背包问题0-1背包问题:给定n中物品和⼀个背包。
物品i的重量为W i,其价值为V i,背包的容量为C。
应如何选择装⼊背包的物品,使得装⼊背包中物品的总价值最⼤?对于每种物品i只有俩种选择,即装⼊背包或不装⼊背包背包问题:与0-1背包问题类似,不同在于选择物品i装⼊背包时,可以选择物品i的⼀部分,⽽不⼀定要全部装⼊背包,1≤i≤n。
这2类问题都具有最优⼦结构性质,极为相似。
背包问题可以⽤贪⼼算法求最优解,0-1背包不能使⽤贪⼼求解。
2.贪⼼解决背包问题步骤贪⼼策略:每次选择单位重量价值最⾼的物品装⼊背包计算每种物品单位重量的价值V iW i,按单位重量的价值从⼤到⼩将n中物品排序。
以排序后的次序依次将物品装⼊背包。
直⾄全部物品都装⼊或者因背包容量不⾜不能装⼊为⽌如果背包尚有容量,将最后不能完全装⼊物品切割⼀部分装满背包算法结束3.代码实现/*** n 物品数* M 背包容量* v[] 物品价值数组* w[] 物品重量数组* x[] 保存最优解路径数组,为1则表⽰该物品完全装⼊,否则装⼊该物品的⼀部分**/void Knapsack(int n, float M, float v[], float w[], float x[]) {// 按照物品单位重量的价值递减排序Sort(n, v, w);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];}Processing math: 100%。
0-1背包问题-贪心法和动态规划法求解
![0-1背包问题-贪心法和动态规划法求解](https://img.taocdn.com/s3/m/69f9004be518964bcf847c24.png)
实验四“0-1”背包问题一、实验目的与要求熟悉C/C++语言的集成开发环境;通过本实验加深对贪心算法、动态规划算法的理解。
二、实验内容:掌握贪心算法、动态规划算法的概念和基本思想,分析并掌握“0-1”背包问题的求解方法,并分析其优缺点。
三、实验题1.“0-1”背包问题的贪心算法2.“0-1”背包问题的动态规划算法说明:背包实例采用教材P132习题六的6-1中的描述。
要求每种的算法都给出最大收益和最优解。
设有背包问题实例n=7,M=15,,(w0,w1,。
w6)=(2,3,5,7,1,4,1),物品装入背包的收益为:(p0,p1,。
,p6)=(10,5,15,7,6,18,3)。
求这一实例的最优解和最大收益。
四、实验步骤理解算法思想和问题要求;编程实现题目要求;上机输入和调试自己所编的程序;验证分析实验结果;整理出实验报告。
五、实验程序// 贪心法求解#include<iostream>#include"iomanip"using namespace std;//按照单位物品收益排序,传入参数单位物品收益,物品收益和物品重量的数组,运用冒泡排序void AvgBenefitsSort(float *arry_avgp,float *arry_p,float *arry_w ); //获取最优解方法,传入参数为物品收益数组,物品重量数组,最后装载物品最优解的数组和还可以装载物品的重量float GetBestBenifit(float*arry_p,float*arry_w,float*arry_x,float u);int main(){float w[7]={2,3,5,7,1,4,1}; //物品重量数组float p[7]={10,5,15,7,6,18,3}; //物品收益数组float avgp[7]={0}; //单位毒品的收益数组float x[7]={0}; //最后装载物品的最优解数组const float M=15; //背包所能的载重float ben=0; //最后的收益AvgBenefitsSort(avgp,p,w);ben=GetBestBenifit(p,w,x,M);cout<<endl<<ben<<endl; //输出最后的收益system("pause");return 0;}//按照单位物品收益排序,传入参数单位物品收益,物品收益和物品重量的数组,运用冒泡排序void AvgBenefitsSort(float *arry_avgp,float *arry_p,float *arry_w ) {//求出物品的单位收益for(int i=0;i<7;i++){arry_avgp[i]=arry_p[i]/arry_w[i];}cout<<endl;//把求出的单位收益排序,冒泡排序法int exchange=7;int bound=0;float temp=0;while(exchange){bound=exchange;exchange=0;for(int i=0;i<bound;i++){if(arry_avgp[i]<arry_avgp[i+1]){//交换单位收益数组temp=arry_avgp[i];arry_avgp[i]=arry_avgp[i+1];arry_avgp[i+1]=temp;//交换收益数组temp=arry_p[i];arry_p[i]=arry_p[i+1];arry_p[i+1]=temp;//交换重量数组temp=arry_w[i];arry_w[i]=arry_w[i+1];arry_w[i+1]=temp;exchange=i;}}}}//获取最优解方法,传入参数为物品收益数组,物品重量数组,最后装载物品最优解的数组和还可以装载物品的重量float GetBestBenifit(float*arry_p,float*arry_w,float*arry_x,float u) {int i=0; //循环变量ifloat benifit=0; //最后收益while(i<7){if(u-arry_w[i]>0){arry_x[i]=arry_w[i]; //把当前物品重量缴入最优解数组benifit+=arry_p[i]; //收益增加当前物品收益u-=arry_w[i]; //背包还能载重量减去当前物品重量cout<<arry_x[i]<<" "; //输出最优解}i++;}return benifit; //返回最后收益}//动态规划法求解#include<stdio.h>#include<math.h>#define n 6void DKNAP(int p[],int w[],int M,const int m); void main(){int p[n+1],w[n+1];int M,i,j;int m=1;for(i=1;i<=n;i++){m=m*2;printf("\nin put the weight and the p:");scanf("%d %d",&w[i],&p[i]);}printf("%d",m);printf("\n in put the max weight M:");scanf("%d",&M);DKNAP(p,w,M,m);}void DKNAP(int p[],int w[],int M,const int m) {int p2[m],w2[m],pp,ww,px;int F[n+1],pk,q,k,l,h,u,i,j,next,max,s[n+1];F[0]=1;p2[1]=w2[1]=0;l=h=1;F[1]=next=2;for(i=1;i<n;i++){k=l;max=0;u=l;for(q=l;q<=h;q++)if((w2[q]+w[i]<=M)&&max<=w2[q]+w[i]){u=q;max=w2[q]+w[i];}for(j=l;j<=u;j++){pp=p2[j]+p[i];ww=w2[j]+w[i];while(k<=h&&w2[k]<ww){p2[next]=p2[k];w2[next]=w2[k];next++;k++;}if(k<=h&&w2[k]==ww){if(pp<=p2[k])pp=p2[k];k++;}else if(pp>p2[next-1]){p2[next]=pp;w2[next]=ww;next++;}while(k<=h&&p2[k]<=p2[next-1])k++;}while(k<=h){p2[next]=p2[k];w2[next]=w2[k];next=next+1;k++;}l=h+1;h=next-1;F[i+1]=next;}for(i=1;i<next;i++)printf("%2d%2d ",p2[i],w2[i]);for(i=n;i>0;i--){next=F[i];next--;pp=pk=p2[next];ww=w2[next];while(ww+w[i]>M&&next>F[i-1]){next=next-1;pp=p2[next];ww=w2[next];}if(ww+w[i]<=M&&next>F[i-1])px=pp+p[i];if(px>pk&&ww+w[i]<=M){s[i]=1;M=M-w[i];printf("M=%d ",M);}else s[i]=0;}for(i=1;i<=n;i++)printf("%2d ",s[i]);}六、实验结果1、贪心法截图:七、实验分析。
用贪心法求解0-1背包问题
![用贪心法求解0-1背包问题](https://img.taocdn.com/s3/m/3b0f82373968011ca3009141.png)
算法设计与分析期末论文题目用贪心法求解“0-1背包问题”专业计算机科学与技术班级09计算机一班学号0936021姓名黄帅日期2011年12月28日一、0-1背包问题的算法设计策略分析1.引言对于计算机科学来说,算法的概念是至关重要的,例如,在一个大型软件系统的开发中,设计出有效的算法将起决定性的作用。
算法是解决问题的一种方法或一个过程。
程序是算法用某种设计语言具体实现描。
计算机的普及极大的改变了人们的生活。
目前,各行业、各领域都广泛采用了计算机信息技术,并由此产生出开发各种应用软件的需求。
为了以最小的成本、最快的速度、最好的质量开发出适合各种应用需求的软件,必须遵循软件工程的原则。
设计一个高效的程序不仅需要编程小技巧,更需要合理的数据组织和清晰高效的素算法,这正是计算机科学领域数据结构与算法设计所研究的主要内容。
2. 算法复杂性分析的方法介绍算法复杂性是算法运行所需要的计算机资源的量,需要时间资源的量称为时间复杂性,需要的空间资源的量称为空间复杂性。
这个量应该只依赖于算法要解的问题的规模、算法的输入和算法本身的函数。
如果分别用N 、I 和A 表示算法要解问题的规模、算法的输入和算法本身,而且用C 表示复杂性,那么,应该有C=F(N,I,A)。
一般把时间复杂性和空间复杂性分开,并分别用T 和S 来表示,则有: T=T(N,I)和S=S(N,I) 。
(通常,让A 隐含在复杂性函数名当中最坏情况下的时间复杂性:最好情况下的时间复杂性:平均情况下的时间复杂性:其中DN 是规模为N 的合法输入的集合;I*是DN 中使T(N, I*)达到Tmax(N)的合法输入; 是中使T(N, )达到Tmin(N)的合法输入;而P(I)是在算法的应用中出现输入I 的概率。
算法复杂性在渐近意义下的阶:渐近意义下的记号:O 、Ω、θ、o 设f(N)和g(N)是定义在正数集上的正函数。
O 的定义:如果存在正的常数C 和自然数N0,使得当N ≥N0时有f(N)≤Cg(N),则称函数f(N)当N 充分大时上有界,且g(N)是它的一个上界,记为f(N)=O(g(N))。
python实现贪婪算法解决01背包问题
![python实现贪婪算法解决01背包问题](https://img.taocdn.com/s3/m/4eaa97f5760bf78a6529647d27284b73f24236cc.png)
python实现贪婪算法解决01背包问题⼀、背包问题01背包是在M件物品取出若⼲件放在空间为W的背包⾥,每件物品的体积为W1,W2⾄Wn,与之相对应的价值为P1,P2⾄Pn。
01背包是中最简单的问题。
01背包的约束条件是给定⼏种物品,每种物品有且只有⼀个,并且有权值和体积两个属性。
在01背包问题中,因为每种物品只有⼀个,对于每个物品只需要考虑选与不选两种情况。
如果不选择将其放⼊背包中,则不需要处理。
如果选择将其放⼊背包中,由于不清楚之前放⼊的物品占据了多⼤的空间,需要枚举将这个物品放⼊背包后可能占据背包空间的所有情况。
⼆、求解思路 当遇到这样的问题,我们可以换⼀种⾓度去思考,假设在⼀个100m3的房⼦⾥⾯,现在要将房⼦装满,同时要保证放⼊的物品个数最多以及装⼊的东西最重,现在⾝边有铁球和棉花,请问⼤家是放铁球进去好呢还是放棉花进去好呢?显⽽易见,放⼊铁球进去是最优选择。
但是原因是什么呢?很简单,就是因为铁球的密度较⼤,相同体积的铁球和棉花相⽐,铁球更重。
不过前提是放⼊第⼀个铁球时,铁球的体积V1⼩于等于100m3 ;放⼊第⼆个铁球时,铁球的体积V2 ⼩于等于(100-V1)m3;……;放⼊第n个铁球时,铁球的体积⼩于等于(100-∑n1Vn-1)m3 ,要是第n个铁球的体积⼤于(100- ∑n1Vn-1)m3 ,还真是不如放点单位体积更轻的棉花进去,说的极端点就是所有铁球的体积都⼤于100m3 ,还真不如随便放⼊点棉花进去合算。
所以总是放铁球进去,不考虑是否放⼊棉花,容易产⽣闲置空间,最终会得不到最优选择,可能只是最优选择的近似选择。
现在再次回到背包问题上,要使得背包中可以获得最⼤总价值的物品,参照铁球的例⼦我们可以知道选择单位重量下价值最⾼的物品放⼊为最优选择。
但是由于物品不可分割,⽆法保证能将背包刚好装满,最后闲置的容量⽆法将单位重量价值更⾼的物品放⼊,此时要是可以将单位重量价值相对低的物品放⼊,反⽽会让背包的总价值和单位重量的价值更⾼。
贪心算法与背包问题的求解策略
![贪心算法与背包问题的求解策略](https://img.taocdn.com/s3/m/f737804a7ed5360cba1aa8114431b90d6c858983.png)
贪心算法与背包问题的求解策略贪心算法是一种常用的优化算法,特别适用于一些具有最优子结构性质的问题。
而背包问题是一个经典的组合优化问题,它涉及到在限定容量下如何选择物品,使得总价值最大化。
本文将探讨贪心算法在背包问题求解中的应用策略。
一、背包问题的定义与分类背包问题是在给定容量的背包和一组物品的情况下,如何选择物品放入背包中,使得物品的总价值最大化。
背包问题可以分为0-1背包问题、分数背包问题和多重背包问题三种。
1. 0-1背包问题:每种物品只能选择放入背包一次或者不放入。
目标是使得背包中物品价值最大化。
2. 分数背包问题:物品可以分割成较小的部分放入背包,即可以选择部分物品放入。
目标是使得背包中物品价值最大化。
3. 多重背包问题:物品有多个可选的数量限制,每种物品可以选择放入多次但不能超过其数量限制。
目标是使得背包中物品价值最大化。
二、贪心算法在背包问题求解中的应用策略在求解背包问题时,贪心算法通常采取以下两种策略:1. 价值密度优先策略:对于0-1背包问题和分数背包问题,贪心算法可以根据物品的单位价值(价值与重量的比率)进行排序,然后按照价值密度从大到小的顺序选择物品放入背包。
这样可以保证每次选择的物品是当前局部最优解,进而得到全局最优解。
算法步骤如下:a) 计算每种物品的单位价值。
b) 对物品按照单位价值进行排序。
c) 从价值最大的物品开始,依次尝试放入背包直至放满或无法继续放入。
2. 数量优先策略:对于多重背包问题,贪心算法可以根据物品的剩余数量进行排序,优先选择剩余数量最多的物品。
这样可以尽可能多地选择该物品,以使总价值最大化。
算法步骤如下:a) 对物品按照剩余数量进行排序。
b) 从剩余数量最多的物品开始,依次尝试放入背包直至放满或无法继续放入。
值得注意的是,贪心算法在某些情况下可能无法得到最优解。
对于一些特殊的背包问题,如存在约束条件或物品具有特殊属性时,贪心算法可能会得出次优解或错误解。
部分背包问题的贪心算法正确性证明
![部分背包问题的贪心算法正确性证明](https://img.taocdn.com/s3/m/43e98f90e43a580216fc700abb68a98270feac57.png)
部分背包问题的贪⼼算法正确性证明⼀,部分背包问题介绍⾸先介绍下0-1背包问题。
假设⼀共有N件物品,第 i 件物品的价值为 V i,重量为W i,⼀个⼩偷有⼀个最多只能装下重量为W的背包,他希望带⾛的物品越有价值越好,请问:他应该选择哪些物品?0-1背包问题的特点是:对于某件(更适合的说法是:某类)物品,要么被带⾛(选择了它),要么不被带⾛(没有选择它),不存在只带⾛⼀部分的情况。
⽽部分背包问题则是:可以带⾛⼀部分。
即,部分背包问题可带⾛的物品是可以⽆限细分的。
(连续与离散的区别)可以把0-1背包问题中的物品想象的⼀个⾦⼦,你要么把它带⾛,要么不带⾛它;⽽部分背包问题中的物品则是⼀堆⾦粉末,可以取任意部分的⾦粉末⼆,部分背包问题的贪⼼算法部分背包问题可以⽤贪⼼算法求解,且能够得到最优解。
贪⼼策略是什么呢?将物品按单位重量所具有的价值排序。
总是优先选择单位重量下价值最⼤的物品。
单位重量所具有的价值:V i / W i举个例⼦:假设背包可容纳50Kg的重量,物品信息如下:物品 i 重量(Kg) 价值单位重量的价值1 10 60 62 20 100 53 30 120 4按照我们的贪⼼策略,单位重量的价值排序:物品1 > 物品2 > 物品3因此,我们尽可能地多拿物品1,直到将物品1拿完之后,才去拿物品2.....最终贪⼼选择的结果是这样的:物品1全部拿完,物品2也全部拿完,物品3拿⾛10Kg(只拿⾛了物品3的⼀部分)这种选择获得的价值是最⼤的。
在(三)会给出证明。
⽽对于0-1背包问题,如果也按“优先选择单位重量下价值最⼤的物品”这个贪⼼策略,那么,在拿了物品1和物品2之后,就不能在拿物品3了。
因为,在拿了物品1和物品2之后,背包中已经装了10+20=30Kg的物品了,已经装不下物品3了(50-30 < 30)(0-1背包:⼀件物品要么拿,要么不拿,否能只拿⼀部分),此时得到的总价值是 160。
Python基于贪心算法解决背包问题示例
![Python基于贪心算法解决背包问题示例](https://img.taocdn.com/s3/m/3f420f39e3bd960590c69ec3d5bbfd0a7956d593.png)
Python基于贪⼼算法解决背包问题⽰例本⽂实例讲述了Python基于贪⼼算法解决背包问题。
分享给⼤家供⼤家参考,具体如下:贪⼼算法(⼜称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。
也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。
贪⼼算法不是对所有问题都能得到整体最优解,关键是贪⼼策略的选择,选择的贪⼼策略必须具备⽆后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。
完全背包问题:给定n个物品和⼀个容量为C的背包,物品i的重量是Wi,其价值为Vi,背包问题是如何选择⼊背包的物品,使得装⼊背包的物品的总价值最⼤,与0-1背包的区别是,在完全背包问题中,可以将物品的⼀部分装⼊背包,但不能重复装⼊。
设计算法的思路很简单,计算物品的单位价值,然后尽可能多的将单位重量价值⾼的物品放⼊背包中。
python实现代码如下:# coding=gbk# 完全背包问题,贪⼼算法import time__author__ = 'ice'class goods:def __init__(self, goods_id, weight=0, value=0):self.id = goods_idself.weight = weightself.value = value# 不适⽤于0-1背包def knapsack(capacity=0, goods_set=[]):# 按单位价值量排序goods_set.sort(key=lambda obj: obj.value / obj.weight, reverse=True)result = []for a_goods in goods_set:if capacity < a_goods.weight:breakresult.append(a_goods)capacity -= a_goods.weightif len(result) < len(goods_set) and capacity != 0:result.append(goods(a_goods.id, capacity, a_goods.value * capacity / a_goods.weight))return resultsome_goods = [goods(0, 2, 4), goods(1, 8, 6), goods(2, 5, 3), goods(3, 2, 8), goods(4, 1, 2)]start_time = time.clock()res = knapsack(6, some_goods)end_time = time.clock()print('花费时间:' + str(end_time - start_time))for obj in res:print('物品编号:' + str(obj.id) + ' ,放⼊重量:' + str(obj.weight) + ',放⼊的价值:' + str(obj.value), end=',')print('单位价值量为:' + str(obj.value / obj.weight))# 花费时间:2.2807240614677942e-05# 物品编号:3 ,放⼊重量:2,放⼊的价值:8,单位价值量为:4.0# 物品编号:0 ,放⼊重量:2,放⼊的价值:4,单位价值量为:2.0# 物品编号:4 ,放⼊重量:1,放⼊的价值:2,单位价值量为:2.0# 物品编号:1 ,放⼊重量:1,放⼊的价值:0.75,单位价值量为:0.75更多关于Python相关内容感兴趣的读者可查看本站专题:《》、《》、《》、《》、《》及《》希望本⽂所述对⼤家Python程序设计有所帮助。
贪心算法实现01背包问题
![贪心算法实现01背包问题](https://img.taocdn.com/s3/m/93ceb9c0d15abe23482f4d63.png)
贪心算法实现01背包问题算法思想:贪心原则为单位价值最大且重量最小,不超过背包最大承重量为约束条件。
也就是说,存在单位重量价值相等的两个包,则选取重量较小的那个背包。
具体实现过程是:首先可以设置一个备份pvu类型的数组,在不破环原数据的情况下,对此备份数组按单位重量价值从大到小的排序。
依次设立两个指针i,j(其中i表示当前应该参与最佳pv值的元素指针,j表示符合约束条件的指针(单位重量价值PV最大,重量最小,不超过最大承重量约束)代码实现如下:#include <iostream>using namespace std;typedef struct{int v;int w;float pv;}pvu;void sortByPv(pvu [],int );int zeroneBags(pvu[],int,int,int * );void print(pvu a[],int n){for (int i=0;i<n;i++){cout<<a[i].w<<" "<<a[i].v<<" "<<a[i].pv<<endl;}cout<<endl;}int main(){int i,maxw;int w[]={1,2,3,2};int v[]={9,10,15,6};int n=sizeof(w)/sizeof(int );const int N=n;pvu arr[N];for (i=0;i<n;i++){arr[i].v=v[i];arr[i].w=w[i];arr[i].pv=v[i]*1.0/w[i];}int remained;cout<<"输入背包的最大承重量:\n";cin>>maxw;cout<<"最大价值为:"<<zeroneBags(arr,n,maxw,&remained)<<"\n还剩"<<remained<<"公斤空间未使用"<<endl;return 0;}void sortByPv(pvu arr[] ,int n){pvu t;int i,j;for (i=0;i<n-1;i++)for (j=0;j<n-1-i;j++)if (arr[j].pv<arr[j+1].pv){t=arr[j];arr[j]=arr[j+1];arr[j+1]=t;}}int zeroneBags(pvu arr[],int n,int maxw,int *e){int i=0,j,minw,totalv=0;int avail=maxw;sortByPv(arr,n); //按最大单位重量价值PV从大到小的排序while (avail&&i<n){minw=i;for (j=0;j<n;j++)if (arr[i].pv==arr[j].pv){if (arr[i].w>arr[j].w&&j>i){minw=j;}}if (arr[minw].w<=avail){avail-=arr[minw].w;totalv+=arr[minw].v;i++;}elsei++;}*e=avail;return totalv; }运行结果截图:。
贪心算法解决0-1背包问题
![贪心算法解决0-1背包问题](https://img.taocdn.com/s3/m/ed699839f46527d3240ce0d7.png)
贪心算法--0-1背包问题1、问题的描述有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,4,2,1,3,它们的价值分别是3,5,6,4,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?贪心算法的思想:贪心原则为单位价值最大且重量最小,不超过背包最大承重量为约束条件。
也就是说,存在单位重量价值相等的两个包,则选取重量较小的那个背包。
2、代码及注释#include <stdio.h>#define M 5//定义一个node结构体,用来存放物体的重量和价值struct node{float value;//价值float weight;//重量int flag; //用来判别这个物体是否装进背包}Node[M],temp;float Value,curvalue=0;//总价值和当前价值float Weight,curweight=0;//背包的最大承受重量和现有重量//按性价比排序void sort(){int i,j;//遍历所有物品for(i=0;i<M-1;i++){//与之后的物品进行比较for(j=i+1;j<M;j++){//判断性价比较最高性价比if((Node[i].value/(float)Node[i].weight)<Node[j].value/(float)Node[j].weight) {//进行交换temp=Node[i];Node[i]=Node[j];Node[j]=temp;}}}}//装载主要方法void load(){int i;//遍历所有物品for(i=0;i<M;i++){//判断加入物品否是否大于背包所能承载的最大重量 if((Node[i].weight+curweight)<=Weight){curvalue+=Node[i].value;curweight+=Node[i].weight;Node[i].flag=1;//进行标记}else{//进行标记Node[i].flag=0;}}}//进行结果的输出void putout(){int i;printf("选中物品的重量分别为:");for(i=0;i<M;i++){if(Node[i].flag){printf("%.2f ",Node[i].weight);}}printf("\n总价值为:%.2f",curvalue);}int main(){int i;printf("请输入物品的重量和价值:\n");for(i=0;i<M;i++){printf("请输入第%d个物品的重量和价值",i+1); scanf("%f%f",&Node[i].weight,&Node[i].value);}printf("\n请输入背包容积:");scanf("%f",&Weight);sort();load();putout();return 0;}3、运行结果(1)在某种情况下可以通过局部最优选择达到整体最优。
贪心法求解背包问题
![贪心法求解背包问题](https://img.taocdn.com/s3/m/3200814a69eae009581bec1c.png)
问题描述
•
已知有n种物品和一个可容纳M重量的背包,每种物品i的重 量为。假定将物品i的一部分放入背包就会得到的效益,这里,, 。显 然,由于背包容量是M,因此,要求所有选中要装入背包的物品总重 量不得超过M.。如果这n件物品的总重量不超过M,则把所有物品装 入背包自然获得最大效益。现需解决的问题是,在这些物品重量的和 大于M的情况下,该如何装包,使得得到更大的效益值。由以上叙述, 可将这个问题形式表述如下: p i xi • 极 大 化目标函数 1i n • 约束条件 wi xi M • 1i n
0 xi 1, pi 0, wi 0,1 i n
算法分析
•
首先需确定最优的量度标准。这里考虑三种策略: • 策略1:按物品价值p降序装包, • 策略2:按物品重w升序装包 • 策略3:按物品价值与重量比值p/w的降序装包 分别以上面三种策略分别求以下情况背包问题的解: • n=7,M=15, 7 • ( p1 ,, p) =(10,5,15,7,6,18,3) • ( w1 ,, w7)=(2,3,5,7,1,4,1)
结果
The end,thank you!
请提问!
与其他算法比较
• 1.贪心法:处理问题的速度快,思想简单。使用该方法的 必要条件是寻找好的贪心法则。不足之处在于很多时候它 只能求的似优解,却不能求的最优解 • 2.动态规划法:可以求解最优解,重点在于徐兆最优决策 序列但是速度较慢。 • 3.分支限界法:可以求解最优解,重点在于寻找限界值。 易求最优解,但是空间花费较高,效率不是很高。 • பைடு நூலகம்择哪一种算法,不仅要根据问题本身还需要考虑到其他 因素,例如时间复杂度,空间复杂度,易求解等等因素。
贪心算法与背包问题的求解策略
![贪心算法与背包问题的求解策略](https://img.taocdn.com/s3/m/52cf4e164a73f242336c1eb91a37f111f1850da1.png)
贪心算法与背包问题的求解策略贪心算法(Greedy Algorithm)是一种常用的算法策略,用于求解最优化问题。
背包问题(Knapsack Problem)则是一个经典的组合优化问题,涉及在限制条件下如何选择物品以最大化价值。
本文将探讨贪心算法在解决背包问题时的应用与求解策略。
一、背包问题简介背包问题是一个常见的动态规划问题,其基本形式为:有一个背包,容量为C(常为非负整数),有n个物品,每个物品的重量为w[i],价值为v[i]。
现在需要从这些物品中选择一部分装入背包,使得在满足背包容量的限制下,所装入物品的总价值最大化。
二、贪心算法的基本思想贪心算法的基本思想是,每一步都选择当前情况下的最优解,希望通过每一步的最优解最终达到全局最优解。
然而,贪心算法并不是适用于所有问题的通用解决方法,它适用于一些特定的问题,如背包问题。
三、贪心算法在背包问题中的应用在背包问题中,常见的贪心策略有两种:按价值密度排序和按重量排序。
下面将分别介绍这两种贪心策略的具体应用。
1. 按价值密度排序按价值密度排序是指将物品按照单位重量的价值从大到小进行排序。
具体操作步骤如下:(1)计算每个物品的价值密度,即v[i]/w[i]。
(2)按照价值密度从大到小的顺序对物品进行排序。
(3)从价值密度最高的物品开始,依次将物品放入背包,直至背包容量达到上限或无物品可放。
2. 按重量排序按重量排序是指将物品按照重量从小到大进行排序。
具体操作步骤如下:(1)按照物品的重量从小到大进行排序。
(2)从重量最小的物品开始,依次将物品放入背包,直至背包容量达到上限或无物品可放。
四、贪心算法的优缺点贪心算法相比其他算法具有简单、高效的特点。
然而,贪心算法并不是万能的,它在某些情况下可能无法得到最优解。
例如,在背包问题中,贪心算法按照价值密度排序的策略并不能保证一定能得到最优解,因为可能存在某些物品的价值密度很高,但重量也很大,无法放入背包。
五、贪心算法的应用场景贪心算法常被应用于一些特定的问题领域,如最小生成树、调度问题、图着色等。
背包问题贪心法和动态规划方案法求解
![背包问题贪心法和动态规划方案法求解](https://img.taocdn.com/s3/m/16b0502f03768e9951e79b89680203d8cf2f6a48.png)
背包问题贪心法和动态规划方案法求解嘿,大家好!今天咱们来聊聊那个让人又爱又恨的背包问题。
这个问题可是算法领域的经典难题,不过别怕,今天我会用贪心法和动态规划两种方法帮你轻松搞定它!来个简单直接的背景介绍。
背包问题,简单来说,就是给定一组物品,每个物品都有一定的价值和重量,你需要在不超过背包承载重量的前提下,挑选出价值最大的物品组合。
听起来是不是有点像生活中的购物决策?哈哈,没错,这就是背包问题的魅力所在。
好,下面咱们直接进入主题。
一、贪心法贪心法,顾名思义,就是每一步都选择当前看起来最优的方案。
对于背包问题,贪心法的核心思想就是:每次都选取价值密度最大的物品。
1.计算每个物品的价值密度,即价值除以重量。
2.然后,按照价值密度从大到小排序。
3.从排序后的列表中依次选取物品,直到背包装满或者没有物品可选。
二、动态规划法动态规划,这是一种更加严谨、也更复杂的方法。
它的核心思想是:通过把大问题分解成小问题,逐步求解,最终得到最优解。
1.定义一个二维数组dp[i][j],表示在前i个物品中选择,背包容量为j时的最大价值。
2.我们考虑第i个物品是否放入背包。
如果放入,则前i-1个物品在容量为j-w[i]时的最大价值加上w[i]的价值,即dp[i][j]=dp[i-1][j-w[i]]+w[i]。
如果不放入,则前i-1个物品在容量为j时的最大价值,即dp[i][j]=dp[i-1][j]。
3.通过比较这两种情况,取最大值作为dp[i][j]的值。
整个过程中,我们需要遍历所有物品和所有可能的背包容量,最终得到dp[n][W]就是我们要找的最大价值。
现在,让我们用一段代码来具体实现一下动态规划法:defknapsack(W,weights,values):n=len(values)dp=[[0for_inrange(W+1)]for_inrange(n+1)]foriinrange(1,n+1):forjinrange(1,W+1):ifj>=weights[i-1]:dp[i][j]=max(dp[i-1][j],dp[i-1][j-weights[i-1]]+values[i -1])else:dp[i][j]=dp[i-1][j]returndp[n][W]测试数据W=50weights=[10,20,30]values=[60,100,120]print(knapsack(W,weights,values))怎么样?是不是觉得动态规划法虽然复杂,但逻辑清晰,更容易找到最优解?通过上面的分析,我们可以看到,贪心法简单高效,但有时候并不能得到最优解;而动态规划法虽然计算复杂度较高,但可以得到最优解。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
fscanf(fp,"%s %d %d\n",&Array[i].name,&Array[i].price,&Array[i].weight);
}
}
fclose(fp);
Array=Input(Array,TotalNum,TotalWeight);
break;
case 2:
printf("请输入物品数量及背包容量\n");
wp[j+1]=temp;
}
}
break;
case 3:
for(i=0;i<TotalNum;i++)
for(j=0;j<TotalNum-i-1;j++)
{
if((float)wp[j].price/(float)wp[j].weight<(float)wp[j+1].price/(float)wp[j+1].weight)
printf("1.空间最优\n");
printf("2.价格最优\n");
printf("3.价格空间比最优\n");
scanf("%d",&Way);
switch(Way)
{
case 1:
for(i=0;i<TotalNum;i++)
for(j=0;j<TotalNum-i-1;j++)
{
if(wp[j].weight>wp[j+1].weight)
{
temp=wp[j];
wp[j]=wp[j+1];
wp[j+1]=temp;r(i=0;i<TotalNum;i++)
for(j=0;j<TotalNum-i-1;j++)
{
if(wp[j].price<wp[j+1].price)
{
temp=wp[j];
wp[j]=wp[j+1];
{
temp=wp[j];
wp[j]=wp[j+1];
wp[j+1]=temp;
}
}
break;
default:
{
printf("输入错误!\n");
exit(1);
}
}
i=0;
RealWeight=wp[0].weight;
TotalPrice=wp[0].price;
printf("被装入背包的物品是:\n(物品名价格重量)\n");
exit(1);
}
}
printf("继续其他数据测试请按1\n");
scanf("%d",&Goon);
}while(Goon==1);
delete Array;
printf("1.文件读入\n");
printf("2.键盘输入\n");
scanf("%d",&InputWay);
switch(InputWay)
{
case 1:
printf("请输入背包最大容量:");
scanf("%d",&TotalWeight);
fp=fopen("data.txt","r");
scanf("%d%d",&TotalNum,&TotalWeight);
if((Array=(Project*)malloc(TotalNum*sizeof(Project)))==NULL)
{
printf("内存已满,申请空间失败!\n");
}exit(1);
}
else
{
printf("请输入:物品名价格重量\n");
贪心法的关键是度量标准,这个程序的度量标准有三个
占用空间最小
物品效益最大
物品效益/占用空间最大
程序实现如下:
至于文件的操作不加论述。
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
char name[10];
int weight;
int price;
}Project;
Project *Input(Project *wp,int TotalNum,int TotalWeight)
{
int i,j,Way,GoBack,RealWeight,RealPrice,TotalPrice;
Project temp;
do{
printf("请选择:\n");
fscanf(fp,"%d\n",&TotalNum);
if((Array=(Project*)malloc(TotalNum*sizeof(Project)))==NULL)
{
printf("内存已满,申请空间失败!\n");
exit(1);
}
else
{
for(i=0;i<TotalNum;i++)
for(i=0;i<TotalNum;i++)
scanf("%s%d%d",&Array[i].name,&Array[i].price,&Array[i].weight);}
Array=Input(Array,TotalNum,TotalWeight);
break;
default:
{
printf("输入错误!\n");
while(RealWeight<TotalWeight&&i<TotalNum)
{
printf("%s%d%d\n",wp[i].name,wp[i].price,wp[i].weight);
i++;
RealWeight+=wp[i].weight;
TotalPrice+=wp[i].price;
}
RealWeight-=wp[i].weight;
TotalPrice-=wp[i].price;
printf("求解结束!背包所装物品总重量:%d,总价值:%d\n",RealWeight,TotalPrice);printf("退出本次测试请按0!\n");
scanf("%d",&GoBack);
}while(GoBack!=0);
return wp;
}
void main()
{
int InputWay,TotalNum,i,TotalWeight,RealWeight,Goon,TotalPrice;
Project *Array;
FILE *fp;
do{
printf("请选择数据录入方式!\n");