贪心算法实验(求解背包问题)

合集下载

贪心算法-01背包问题

贪心算法-01背包问题

贪⼼算法-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)计算时间。

贪心算法求连续背包问题

贪心算法求连续背包问题

实验项目名称:贪心算法求连续背包问题一、实验目的:明确连续背包问题的概念;利用贪心算法解决连连续续背包问题;并通过本例熟悉贪心算法在程序设计中的应用方法。

二、实验原理: 贪心算法原理:在贪婪算法(greedy method )中采用逐步构造最优解的方法。

在每个阶段,都作出一个看上去最优的决策(在一定的标准下)。

决策一旦作出,就不可再更改。

作出贪婪决策的依据称为贪婪准则(greedy criterion )。

三、实验内容与步骤:贪心算法求连续背包问题问题描述:已知n 个物体和1个背包,其中物体i 有重量w i 和价值v i ,背包承重量为W 。

求一装载方案,要求在不超过背包负重的前提下,背包中装入的物品价值最大。

很明显,如果1ni i w W =≤∑,则最优解就是装入全部物体,因此下面假设1n i i w W =>∑。

注:连续背包问题中的物体可以任意分割,即部分装入背包。

分析:连续背包问题可形式化为如下模型:{}11max ..[0,1],1,,ni ii ni ii i x v x w W s t x i n ==⎧≤⎪⎨∈∈⎪⎩∑∑对于连续背包问题,可用贪心技术求得最优解。

贪心策略是单位重量价值高者优先。

例如:所给物体的重量和价值如下,则,程序可以得到如下结果:最大价值为163.0;所选各物体的数量为:1.0 1.0 1.0 0.8参考程序段如下//连续背包问题的贪心算法,最大单位重量价值优先//输入:各物体重量w 、价值v 和背包重量W ,已按v/w 降序排列#include<stdio.h>int knapsack(int n1,float w1[],float v1[],float W1){ int i; float weight; float x[10],s=0; for(i=1;i<=n1;i++) x[i]=0; weight=0; i=1;while(weight<W1) {if(weight+w1[i]<W1){x[i]=1;weight=weight+w1[i];}else{x[i]=(W1-weight)/w1[i];weight=W1;}i++;}for(i=1;i<=n1;i++) s=s+x[i]*v1[i];printf("背包所能容纳商品的最大价值为:%f\n",s);printf("所选择的商品的一个序列为:\n");for(i=1;i<=n1;i++)printf("%8.3f",x[i]);}void main(){int n,i,j;float w[10],v[10],W;clrscr();printf("输入商品数量n 和背包容量W:\n");scanf("%d,%f",&n,&W);printf("输入每件商品的重量,价值:\n");for(i=1;i<=n;i++)scanf("%f,%f",&w[i],&v[i]);knapsack(n,w,v,W);printf("\n");system("pause");}。

贪心算法实验(求解背包问题)

贪心算法实验(求解背包问题)

算法分析与设计实验报告第四次实验
}
}
输入较小的结果:
测试结

输入较大的结果:
附录:
完整代码(贪心法)
;
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背包贪心算法

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背包问题

贪心法的关键是度量标准,这个程序的度量标准有三个占用空间最小物品效益最大物品效益/占用空间最大程序实现如下:至于文件的操作不加论述。

#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;}。

贪心算法背包问题

贪心算法背包问题
算法设计与分析实验报告
题目:贪心算法
背包问题
专业:JAVA 技术 09——02 班 学号:540913100201 姓名:柏顺顺 指导老师:宋胜利
实验三:贪心算法
一、实验目的与要求
1、掌握背包问题的算法 2、初步掌握贪心算法
背包问题
二、实验题:
问题描述:与 0-1 背包问题相似,给定 n 种物品和一个背包。物品 i 的重量是 wi,其价 值为 vi,背包的容量为 c。与 0-1 背包问题不同的是,在选择物品 i 装入背包时,背包问题 的解决可以选择物品 i 的一部分,而不一定要全部装入背包,1< i < n。
JOptionPane.showMessageDialog(null, "重量不能为空!"); return; } else{ if (s1.equals("")){ JOptionPane.showMessageDialog(null, "效益值不能为空!"); return; }else { if (s3.equals("")) JOptionPane.showMessageDialog(null, "总重量不能为空!"); return; } } } catch (Exception e3) { // TODO: handle exception }
}
//可以执行贪心算法了 int [] wCopy = new int [w.length]; int [] pCopy = new int [w.length]; float temp2; int temp1; float totalx=0; float [] x = new float [w.length];//效益和重量的比值 float [] n =new float[w.length];//记录个数 float [] nCopy = new float[w.length]; for(int i=0;i<w.length;i++) { wCopy [i] = w[i]; pCopy [i] = p[i]; } for (int i=0;i<w.length;i++) x[i] = (float) ((p[i]*1.0)/w[i]); for(int i= 0;i<w.length;i++) for(int j=i+1;j<w.length;j++)

贪心法解决背包问题

贪心法解决背包问题

算法分析实验报告贪心法解决背包问题学生姓名:专业:班级:学号:指导教师: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升序装包,因为这可以装入尽可能多的物品,从而增加背包总价值。

但是,虽然每一步选择使背包得容量消耗得慢了,但背包价值却没能保证迅速增长,从而不能保证目标函数达到最大。

贪婪法求解背包问题

贪婪法求解背包问题

贪婪法求解背包问题-CAL-FENGHAI.-(YICAI)-Company One1实验二贪婪法一、实验目的1)理解和掌握贪婪算法的基本思想;2)使用贪婪算法求解背包问题以及最小花费生成树问题。

二、方法原理贪心算法就是做出一系列选择,使原问题达到最优解。

在每一个决策点,都是做出当前看来的最优选择。

三、实验设备PC机一台,C语言、PASCAL语言、Matlab任选四、方法原理贪心算法就是做出一系列选择,使原问题达到最优解。

在每一个决策点,都是做出当前看来的最优选择。

五、实验内容1)利用贪婪法求如下背包问题的最优解:n=5,M=100,价值P={20,30,66,40,60 },重量为w={10,20,30,40,50}。

六、实验要求1)认真分析题目的条件和要求,复习相关的理论知识,选择适当的解决方案和算法;2)编写上机实验程序,作好上机前的准备工作;3)上机调试程序,并试算各种方案,记录计算的结果(包括必要的中间结果);4)分析和解释计算结果;5)按照要求书写实验报告;源代码:#include<stdio.h>#include<stdlib.h>#include<iostream>using namespace std;#define n 5#define M 100typedef struct {int s;float p;//价值float w;float t;//价值重量比float x;}OBJECT;OBJECT obj[n];void swap(float &x, float &y) {float t;t = x;x = y;y = t;}float divide_and_conquer(OBJECT obj[], int low, int high) { int k, i = low;float z = obj[low].t;for (k = low + 1; k <= high; k++) {if (obj[k].t>z) {i += 1;if (i != k)swap(obj[i], obj[k]);}}swap(obj[low], obj[i]);return i;}void quick_sort(OBJECT obj[], int low, int high) {int k;if (low < high) {k = divide_and_conquer(obj, low, high);quick_sort(obj, low, k - 1);quick_sort(obj, k + 1, high);}}void sort_recover(OBJECT obj[]) {int i, j,temp;for (i = 0; i < n-1; i++) {for (j = 0; j < n - 1 - i; j++) {if (obj[j].s > obj[j + 1].s)swap(obj[j], obj[j + 1]);}}}float knapsack_greedy(OBJECT obj[]) {int i;float m,r=0;for(i=0;i<n;i++){obj[i].t=obj[i].p/obj[i].w;obj[i].x = 0;}quick_sort(obj,0,4);m = M;printf(" 物体价值重量价值重量比结果\n");printf("=========================================\n");for (i = 0; i < n; i++) {if (obj[i].w <= m) {obj[i].x = 1;m -= obj[i].w;r += obj[i].p;}else {obj[i].x = m / obj[i].w;r += obj[i].x * obj[i].p;break;}}return r;}void main() {int i;float r;//float x[] = { 0 };float s[] = { 1,2,3,4,5 };float p[]={ 20,30,66,40,60 };float w[]={ 10,20,30,40,50 };for (i = 0; i < n; i++) {obj[i].s = s[i];obj[i].p = p[i];obj[i].w = w[i];}r = knapsack_greedy(obj);sort_recover(obj);for (i = 0; i < n; i++) {printf(" %d %2.0f %2.0f %2.1f %1.1f\n", obj[i].s, obj[i].p, obj[i].w, obj[i].t, obj[i].x);}printf("\n最大价值为:%f\n",r );printf("背包问题的解向量:X={");for (i = 0; i < n; i++) {printf("%1.1f",obj[i].x);if(i<4)printf(",");}printf("}");system("pause");}结果:。

0-1背包问题-贪心法和动态规划法求解

0-1背包问题-贪心法和动态规划法求解

实验四“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、贪心法截图:七、实验分析。

使用JAVA实现算法——贪心算法解决背包问题

使用JAVA实现算法——贪心算法解决背包问题

使⽤JAVA实现算法——贪⼼算法解决背包问题解释等全部在代码中,⾃⼰跑了下,是没问题的package BasePart;import java.io.BufferedReader;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStreamReader;/*** 使⽤贪⼼算法解决背包问题* 背包问题:* 旅⾏者有背包容量m公⽄* 现在有重量W1,W2,W3,W4....Wn* 对应的价值V1,V2,V3,V4....Vn* 运⾏重复携带,欲求得最⼤价值* 贪⼼算法:求得最好的选择,但是贪⼼算法不是对于所有的问题都得到整体最优解* 贪⼼算法基本思路:* 1.建⽴数学模型来描述问题* 2.把求解问题分成若⼲个⼦问题* 3.对于每⼀个⾃问题求得局部最优解* 4.把⼦问题的解局部最优解合成原来解问题的⼀个解* 贪⼼算法的实现过程:* 从⼀个初始解出发* while-do朝总⽬标前进* 求出可⾏解的⼀个解元素* 由所有解元素组成合成问题的⼀个可⾏解*/public class Greedy {/*解决背包问题*需要背包容量*背包价值*背包剩余容量*解向量集合*/private double total_weight;private double total_value;private double rest_weight;//储存排序数组private Good[] arrayValue;private Good[] arrayWeight;private Good[] arrayC_P;private int goodsNum;private Good[] goods;private double real_weight;public Greedy() {}public Greedy(int goodsNum,double total_weight) {this.goodsNum=goodsNum;this.total_weight=total_weight;}public void init(String filename) throws IOException {/** 1.初始化程序* 2.从TXT⽂件中得到商品重量和其价值数组* 3.初始化序列数组arrayValue/Weight/C_P*/goods=new Good[goodsNum];BufferedReader data=new BufferedReader(new InputStreamReader(new FileInputStream(filename)));String buff;String[] strs;//循环赋值for(int i=0;i<4;i++){buff=data.readLine();strs=buff.split(" ");//根据位次goods[i]=new Good();//对象数组不仅仅需要初始化数组,对于数组内的每⼀个对象也需要初始化goods[i].setName(strs[0]);goods[i].setValue(Double.parseDouble(strs[1]));goods[i].setWeight(Double.parseDouble(strs[2]));goods[i].figureC_P();}//关闭输⼊流//成员变量初始化arrayValue=new Good[goodsNum];arrayWeight=new Good[goodsNum];arrayC_P=new Good[goodsNum];//初始化数组/** 价值由⼤到⼩数组*/arrayValue=arrayCopy(goods, arrayValue);//按照价值对arrayValue数组进⾏重新排列,使⽤冒泡排序法for(int i=0;i<goodsNum-1;i++){//从⼤到⼩排列for(int j=i+1;j<goodsNum;j++){if(arrayValue[i].getValue()<arrayValue[j].getValue()){Good temp=arrayValue[i];arrayValue[i]=arrayValue[j];arrayValue[j]=temp;}}}/**质量由⼩到⼤数组*/arrayWeight=arrayCopy(goods, arrayWeight);//按照价值对arrayWeight数组进⾏重新排列,使⽤冒泡排序法for(int i=0;i<goodsNum-1;i++){//从⼩到⼤排列for(int j=i+1;j<goodsNum;j++){if(arrayWeight[i].getWeight()>arrayWeight[j].getWeight()){Good temp=arrayWeight[i];arrayWeight[i]=arrayWeight[j];arrayWeight[j]=temp;}}}/** 性价⽐由⼤到⼩排列*/arrayC_P=arrayCopy(goods, arrayC_P);//按照价值对arrayC_P数组进⾏重新排列,使⽤冒泡排序法for(int i=0;i<goodsNum-1;i++){//从⼤到⼩排列for(int j=i+1;j<goodsNum;j++){if(arrayC_P[i].getC_P()<arrayC_P[j].getC_P()){Good temp=arrayC_P[i];arrayC_P[i]=arrayC_P[j];arrayC_P[j]=temp;}}}}//⽤于数组拷贝public Good[] arrayCopy(Good[] goods,Good[] arr2){arr2=goods.clone();return arr2;}private void show(Good[] goodsarr) {for(Good good:goodsarr){System.out.println(good.getName()+"\t"+good.getValue()+"\t"+good.getWeight()+"\t"+good.getC_P()+"\t"+good.getNum()); }}/*三种策略:度量准则* 依次选取价值最⼤填充* 依次选取重量最轻填充* 依次选取⽐价最⼤填充** ⽅法设计:* 按照度量准则* 传递⼀个按照选择优先级排列的对象数组* 迭代计算剩余容量* 返回设计⽅案*/public void strategy(Good[] goodsArray){rest_weight=total_weight;for(Good good:goodsArray){int selectNum=(int)Math.floor(rest_weight/good.getWeight());rest_weight=rest_weight-selectNum*good.getWeight();good.setNum(selectNum);if(rest_weight<arrayWeight[0].getWeight()){continue;}}}public void calculate(Good[] goodsArray,String target){total_value=0;real_weight=0;//处理结果System.out.println("在以"+target+"为准则的情况下");for(Good good:goodsArray){System.out.println(good.getName()+"\t\t数量:"+good.getNum());total_value+=good.getValue()*good.getNum();real_weight+=good.getWeight()*good.getNum();}System.out.println("总价值是:\t"+total_value+"\t总重量是:\t"+real_weight); }public void solve() {/** 业务逻辑* 将优先级数组*/strategy(arrayValue);calculate(arrayValue,"价值");strategy(arrayWeight);calculate(arrayWeight,"重量");strategy(arrayC_P);calculate(arrayC_P,"⽐值");}public static void main(String[] args) throws IOException {Greedy greedy=new Greedy(4,50);greedy.init("goods.txt");greedy.solve();}}Txt⽂本为:ad钙奶 12 5ab胶带 6 1电脑 4000 30⾳响 500 15说明:第⼀列:名称第⼆列:价格第三列:重量程序运⾏结果为:待改善。

背包问题的贪心算法

背包问题的贪心算法

Wi Xi
16.5 20 20 20
Vi X i
24.25 28.2 31 31.5
先检验这四个为可行解*,即满足约束条件(4.2.2),(4.2.3).再比 较目标函数值,∑vixi .知④组解效益值最大.该组解是背包问题的最 优解。(见定理4.2)
6
例4.4 n=3,c=20, (V1,V2,V3) (25, 24,15) (W1,W2,W3) (18,15,10)
7
,且物品2的24/15 = v2/w2 较物品3的15/10= v3/w3效益值高。按 此选择策略,得②即(1, 2/15, 0),∑vixi=28.2 .此解是一个次优解。 显然,按物品效益值的非增次序装包不能得最优解。
原因:背包可用容量消耗过快。
(2)以容量作为量度。即按物品重量的非降次序将物
—选取最优的量度标准实为用贪心方法求解问题的核心.
16
4.3 贪心算法的基本要素
1.贪心选择性质
所谓贪心选择性质是指所求问题的整体最优解可以 通过一系列局部最优的选择,即贪心选择来达到。这 是贪心算法可行的第一个基本要素,也是贪心算法与 动态规划算法的主要区别。
动态规划算法通常以自底向上的方式解各子问 题,而贪心算法则通常以自顶向下的方式进行,以迭 代的方式作出相继的贪心选择,每作一次贪心选择就 将所求问题简化为规模更小的子问题。
品装包。如例4.4中的解③(让背包尽可能慢被消耗)
排序 : (w3,w2,w1)= (10,15,18)
(V3,V2,V1) (15, 24, 25)
V3=15,x3=1,w3=10,背包剩余C-10=10;物品2有次大重量(w2=15), 但包装不下。使用x2=2/3,刚好装满背包且物品2装入2/3与物品1 装入5/9的容量均为10个单位。但前者的效益值24×2/3=16 >后者

算法设计和分析实验四:贪心算法求解背包问题

算法设计和分析实验四:贪心算法求解背包问题

实验五:贪心算法求解背包问题实验内容应用贪心算法求解离散背包问题,分析时间复杂度。

有一个承重为W的背包和n个物品,它们各自的重量和价值分别是wi和vi (1<=i<=n),设求这些物品中最有价值的一个子集。

如果每次选择某一个物品的时候,只能全部拿走,则这一问题称为离散(0-1)背包问题;如果每次可以拿走某一物品的任意一部分,则这一问题称为连续背包问题。

算法思想•动态规划的思想:–对较小的子问题进行一次求解,并把结果记录下来,然后利用较小问题的解,求解出较大问题的解,直到求解出最大问题的解。

–引进一个二维数组ch[MAX][MAX],用ch[i][j]记录CH1与CH2的LCS的长度,b[i][j]记录ch[i][j]是通过哪一个子问题的值求得的,以决定搜索的方向。

我们是自底向上进行递推计算,那么在计算ch[i,j]之前,ch[i-1][j-1],ch[i-1][j]与ch[i][j-1]均已计算出来。

此时我们根据CH1 [i] = CH2[j]还是CH1[i] !=CH2[j],就可以计算出ch[i][j]。

算法length(string CH1,string CH2,int b[MAX][MAX])//用于构建动态数组//输入:两字符窜//输出:最长公共子序列for(i=1;i<=ch1Len;i++)//二重循环求解for(int j=1;j<=ch2Len;j++){if(CH1[i-1]==CH2[j-1])//相等字符{ch[i][j]=ch[i-1][j-1]+1;b[i][j]=0;}else if(ch[i-1][j]>=ch[i][j-1])//上比较大{ch[i][j]=ch[i-1][j];b[i][j]=1;}else//左比较大{ch[i][j]=ch[i][j-1];b[i][j]=-1;}}printCS(int b[MAX][MAX],string x,int i,int j) //回溯求出最长子序列输出//输入:标记数组//输出:最长子序列if(i == 0 || j == 0)//边界,返回return;if(b[i][j] == 0){printCS(b, x, i-1, j-1);//左上cout<<x[i-1]<<" ";}else if(b[i][j] == 1)printCS(b, x, i-1, j);//上elseprintCS(b, x, i, j-1);//左源程序//应用贪心算法求解离散背包问题#include<iostream>using namespace std;#define MAX 100//结构体struct Elem{double W;double V;double P;int number;};//顺序表struct SqList{Elem *elem;int length;int listsize;};//构造一个空的线性顺序表void InitList_Sq(SqList &L){L.elem=(Elem *)malloc(100*sizeof(Elem)); L.length=0;L.listsize=100;}//******************************** //构造背包,顺序表//******************************void input(SqList &L){cout<<"请输入物品的个数:";cin>>L.length;for(int i=0;i<L.length;i++){cout<<"请输入第"<<i+1<<"个物品的重量和价值:";cin>>L.elem[i].W>>L.elem[i].V;L.elem[i].P=L.elem[i].V/L.elem[i].W;cout<<"价值比为:"<<L.elem[i].P<<endl;L.elem[i].number=i+1;}}//*********************************//插入排序由大到小//*******************************void inser(SqList &L){Elem inserter;int index;//inserter待插入合适位置的元素,index指示插入位置for(int pass=1;pass<L.length;pass++){//共比较size-1轮inserter=L.elem[pass];//第pass轮时,待插入的对象是a[pass] index=pass-1;while(index>=0&&inserter.P>L.elem[index].P){ //寻找插入位置L.elem[index+1]=L.elem[index];index--;//指针前移,再比较}L.elem[index+1]=inserter;//跳出while时,找到插入位置}//end of forcout<<"按照价值比由大到小排列的顺序为:";for(pass=0;pass<L.length;pass++)cout<<L.elem[pass].number<<" ";cout<<endl;}//*************************************************8 //背包程序//采用贪心算法//根据价值和重量的比来实现贪心算法//************************************************ void bag(SqList L){double w,sumV=0,sumW=0;int list[MAX],a=0;cout<<"请输入背包承重量W:";cin>>w;inser(L);for(int i=0;i<L.length;i++){while(sumW+L.elem[i].W<=w){sumW=sumW+L.elem[i].W;sumV=sumV+L.elem[i].V;list[a++]=L.elem[i].number;}}cout<<"最后包里的总重量为:"<<sumW<<endl; cout<<"最后包里的总价值为:"<<sumV<<endl; cout<<"放到背包中的物品的序号列表为:"; for(i=0;i<a;i++){cout<<list[i]<<" ";}}int main(){cout<<"贪心算法求解背包问题"<<endl;SqList L;InitList_Sq(L);input(L);bag(L);return 0;}实验结论1、运行截图查找最长公共子序列长度时的动态规划两个for循环,时间复杂度为O(n*n)。

贪心算法背包问题

贪心算法背包问题

《算法设计与分析》实验报告2015-2016年第2学期实验班级:学生姓名:学号:指导老师:信息工程学院实验项目名称:贪心算法背包问题实验日期:2016年4月12日一、实验类型:□√验证性□设计性二、实验目的1、掌握背包问题的算法2、初步掌握贪心算法三、实验内容及要求问题描述:与0-1背包问题相似,给定n种物品和一个背包。

物品i的重量是wi,其价值为vi,背包的容量为c。

与0-1背包问题不同的是,在选择物品i装入背包时,背包问题的解决可以选择物品i的一部分,而不一定要全部装入背包,1< i < n。

四、实验步骤#include "iostream.h"#include "stdio.h"#include <cstdlib>struct stone{ int name;int weight;//物品的剩余重量int weight_t;//物品的重量float benefit;//物品的价值//float b;};void sort(stone *data,int num){if(num<1)return;int low=0,high=num;stone key_s=data[low];float key=(float)key_s.benefit/key_s.weight;int empty=low;while(low<high){ if(low==empty){ while((data[high].benefit/data[high].weight<key) &&(high>low)){ high--;}if(data[high].benefit/data[high].weight>=key){ data[low]=data[high];empty=high;}}else if(high==empty) {while((data[low].benefit/data[low].weight>=key)&&(low<h igh)){ low++; }if(data[low].benefit/data[low].weight<key){ data[high]=data[low];empty=low; }}}data[empty]=key_s;if(empty>1)sort(data,empty-1);if(num-empty-1>0)sort(data+empty+1,num-empty-1);}void inputstone(stone *bag,int num){ for(int i=0;i<num;i++){ bag[i].name=i+1;printf("请输入第%d号物品的重量:",i+1); scanf("%d",&bag[i].weight);if (bag[i].weight<=0){printf("物品的重量必须大于0!\n");} printf("请输入第%d号物品的价值:",i+1); scanf("%f",&bag[i].benefit);if (bag[i].benefit<=0){printf("物品的价值必须大于0!\n");}bag[i].weight_t=bag[i].weight;}}int main(int argc, char* argv[]){ int i;int num=0;int weight=0;float benefit=0;stone *bag;do{ printf("请输入背包可容纳的重量:"); scanf("%d",&weight);if (weight<=0)printf("背包可容纳的重量必须大于0!\n"); }while(weight<=0);do{ printf("请输入物品的数量:");scanf("%d",&num);if (num<=0)printf("物品数量必须大于0!\n");}while(num<=0);bag=new stone[num];inputstone(bag,num);sort(bag,num-1);for(i=0;i<num&&weight>0;i++){ stone *temp=bag+i;if(weight>=temp->weight){ weight-=temp->weight;temp->weight=0;benefit+=temp->benefit;continue;}else{ temp->weight-=weight;weight=0;benefit+=(temp->benefit*(1-(float)temp->weight/temp->we ight_t));break;} }printf("物品种类放入的比例每单位效益\n");for(i=0;i<num;i++){ stone *temp=bag+i;printf("%d类物品",temp->name);printf("\t\t%.2f\t\t",(temp->weight_t-temp->weight)/(fl oat)temp->weight_t);printf(" %.4f\n",temp->benefit/(float)temp->weight_t) ;}printf("总效益:%.2f",benefit);delete bag;getchar();system("PAUSE");return EXIT_SUCCESS;return 0;}五、实验结果1、实验图形2、结果分析如上面第一个图所示当输入背包可容纳的重要为21,输入物品的数量为3,输入第1号物品的重量为8,输入第1号物品的价值为12,输入第2号物品的重量为9,输入第2号物品的价值为16,输入第3号物品的重量为4,输入第3号物品的价值为15,则可以得出总效益为43.00。

python实现贪婪算法解决01背包问题

python实现贪婪算法解决01背包问题

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 ,还真不如随便放⼊点棉花进去合算。

所以总是放铁球进去,不考虑是否放⼊棉花,容易产⽣闲置空间,最终会得不到最优选择,可能只是最优选择的近似选择。

现在再次回到背包问题上,要使得背包中可以获得最⼤总价值的物品,参照铁球的例⼦我们可以知道选择单位重量下价值最⾼的物品放⼊为最优选择。

但是由于物品不可分割,⽆法保证能将背包刚好装满,最后闲置的容量⽆法将单位重量价值更⾼的物品放⼊,此时要是可以将单位重量价值相对低的物品放⼊,反⽽会让背包的总价值和单位重量的价值更⾼。

Python基于贪心算法解决背包问题示例

Python基于贪心算法解决背包问题示例

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程序设计有所帮助。

贪心法求解背包问题

贪心法求解背包问题
贪心法求解背包问题
问题描述

已知有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.分支限界法:可以求解最优解,重点在于寻找限界值。 易求最优解,但是空间花费较高,效率不是很高。 • பைடு நூலகம்择哪一种算法,不仅要根据问题本身还需要考虑到其他 因素,例如时间复杂度,空间复杂度,易求解等等因素。

贪心算法求解背包问题C语言描述

贪心算法求解背包问题C语言描述

贪心算法求解背包问题:#include<stdio.h>#define maxnumber 20typedef struct node{float w;float v;int i;}Object;float find(Object wp[],int n,float M) {float x[maxnumber];int i;float maxprice=0;for(i=1;i<=n;i++)//初始化x[n];{x[i]=0.0;}i=0;while(wp[i].w < M){x[wp[i].i]=1;M=M-wp[i].w;i++;}x[wp[i].i]=M/wp[i].w;//输出解向量printf("解向量是:\n");for(i=1;i<=n;i++){printf("x[%d]=%f",i,x[i]);}printf("\n");//计算最大价值for(i=0;i<n;i++){maxprice=maxprice+wp[i].v*x[wp[i].i];}return maxprice;}void main(){Object wp[maxnumber];int i,j,n;float C;//背包的重量int flag;float maxprice,temp;printf("请输入物品的种数:");scanf("%d",&n);printf("请输入背包的重量:");scanf("%f",&C);printf("\n请输入物品的序号、重量和价值:");for(i=0;i<n;i++){scanf("%d",&wp[i].i);scanf("%f",&wp[i].w);scanf("%f",&wp[i].v);}printf("\n输入的物品是:\n");//输出物品for(i=0;i<n;i++){printf(" %d",wp[i].i);printf(" %f",wp[i].w);printf(" %f",wp[i].v);printf("\n");}//用冒泡排序对物品按照单位价值进行降序排序for(i=1;i<n;i++){flag=0;for(j=n-1;j>=i;j--){if(wp[j-1].v/wp[j-1].w < wp[j].v/wp[j].w){temp=wp[j-1].i;wp[j-1].i=wp[j].i;wp[j].i=temp;temp=wp[j-1].w;wp[j-1].w=wp[j].w;wp[j].w=temp;temp=wp[j-1].v;wp[j-1].v=wp[j].v;wp[j].v=temp;flag=1;}if(flag==0)break;}}printf("\n排序后的物品是:\n");//输出物品for(i=0;i<n;i++){printf(" %d",wp[i].i);printf(" %f",wp[i].w);printf(" %f",wp[i].v);printf("\n");}maxprice=find(wp,n,C);printf("\n物品的重价值为:%f",maxprice);}。

贪心算法实现背包问题算法设计与分析实验报告

贪心算法实现背包问题算法设计与分析实验报告

算法设计与分析实验报告实验名称 贪心算法实现背包问题 评分 实验日期 年 月 日 指导教师 姓名 专业班级 学号一.实验要求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件物品的效益值和重量。

2贪心算法解决部分背包问题

2贪心算法解决部分背包问题

2贪心算法解决部分背包问题一、实验目的学习掌贪心算法法思想。

二、实验内容用贪心法解决部分背包问题。

给定n种物品和一个背包。

物品i的重量是Wi,其价值为pi,背包的容量为M,将物品i的一部分xi放入背包会得到pi xi的效益。

应如何选择装入背包的物品,使得装入背包中物品的总价值最大?给出具体的装包方案。

在选择装入背包的物品时,对每种物品i,可以整件装入背包、不装入背包或部分装入背包。

但不能将物品i装入背包多次。

四、需求分析对于给定n种物品和一背包。

在容量最大值固定的情况下,要求装入的物品价值最大化。

五、基本思想:贪婪法是解决最优化问题时的一种简单但适用范围有限的策略。

总是对当前的问题作最好的选择,也就是局部寻优。

最后得到整体最优。

总是选择单位价值最高的物品。

六、详细设计#include<iostream>using namespace std;struct _Object//物品结构体{int Value;//物品价值int Weight;//物品重量int AveValue;//物品单位价值float Num;//物品可以放入的数量void knaspsack(int n,float M,_Object object[]){ //n为物品个数,M为背包容量int i;float C=M;for(i=0;i<n;i++){object[i].Num=0;//初始化放入背包的物品为0if(object[i].Weight>C)break;//当物品重量大于背包容量时else//小于时{object[i].Num=1;//物品i放入一件C-=object[i].Weight;//背包容量减小}}if(i<=n)//当不能放入整个物品时,选取物品一部分放入object[i].Num=C/object[i].Weight;for(i=0;i<n;i++){if(object[i].Num>0)cout<<"重量为: "<<object[i].Weight<<" 价值为: "<<object[i].Value<<" 的物品放入"<<object[i].Num<<" 件"<<endl;}}void SortObject(_Object object[],int n)//将各个物品按单位价值进行排序{int j;_Object temp;int i;for(i=0;i<n;i++)object[i].AveValue=object[i].Value/object[i].Weight;//各个物品的单位价值for(i=0;i<n-1;i++)//根据物品的单位价值对物品进行从大到小的冒泡排序{for(j=0;j<n-i-1;j++){if(object[j].AveValue<object[j+1].AveValue){temp=object[j];object[j]=object[j+1];object[j+1]=temp;}}}}int main(){_Object object[4];//4个物品int M=9;//背包容量为15object[0].Weight=2;object[0].Value=3;object[1].Weight=3;object[1].Value=4;object[2].Weight=4;object[2].Value=5;object[3].Weight=5;object[3].Value=7;SortObject(object,4);knaspsack(4,M,object);}七、结果分析:对于0-1背包问题,贪心算法之所以不能得到最优解是因为在这种情况下,它无法保证最后能将背包装满,部分闲置的背包空间,使每公斤背包的价值降低了。

贪心算法实现01背包问题

贪心算法实现01背包问题

贪心算法实现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; }运行结果截图:。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
算法分析与设计实验报告
第四次实验
姓名
学号
班级
时间
上午
地点工训楼309实名称贪心算法实验(求解背包问题)
实验目的
通过上机实验,要求掌握贪心算法的问题描述、算法设计思想、程序设计。
实验原理
给定任意几组数据,利用贪心算法的思想,将物品装入背包并使得其价值最大。
程序思路:
与0-1背包问题类似,所不同的是在选择物品i装入背包时,可以选择物品i的一部分,而不一定要全部装入背包,1≤i≤n。
x[j]=tem[i];
}
}
}
测试结果
输入较小的结果:
输入较大的结果:
实验心得
首先这个实验,需要注意的点是背包问题与0-1背包不同,物品可以部分的放入背包中,所以思路也不一样,首先就是将物品按照单位质量价值排序,只这一点就有一点难度。难度在于要是排序后物品的编号就会发生改变,输出的就不是之前的编号的物品,导致错误,后来发现如果为每一个物品保存一个副本,然后将它们的编号进行对比,就可以进行正确的输出了。其中这个实验让我学到了两点:一是结构体的使用,之前一直没有怎么用过,现在才发现自己其实不会用;二十对于库函数sort函数的使用。感觉每一次实验都有学到东西,很开心。
实验得分
助教签名
附录:
完整代码(贪心法)
;
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; ;
sort(item,item+n,comparison); >c)
(4)依此策略一直地进行下去,直到背包装满为止。
关键代码
boolcomparison(st a,st b){ ;
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])
break;
tem[i]=1;
c-=item[i].w;
}
if(i<n) ;
for(i=0;i<n;i++) ==tmp[j])
x[j]=tem[i];
}
}
}
(1)首先将单位重量的平均价值排序。
(2)根据背包容量依次将平均价值高的物品放入背包中。
实验步骤
(1)首先计算每种物品单位重量的价值vi/wi;
(2)依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包;
(3)若将这种物品全部装入背包后,背包内的物品总重量未超过C,则选择单位重量价值次高的物品并尽可能多地装入背包;
相关文档
最新文档