贪婪法求解背包问题

合集下载

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

背包问题解析(一)-贪心算法

背包问题解析(一)-贪心算法

背包问题解析(⼀)-贪⼼算法⼀、题⽬:有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)打印结果:四、算法分析:贪⼼选择是指所求问题的整体最优解可以通过⼀系列局部最优的选择,即贪⼼选择来达到。

贪心算法求连续背包问题

贪心算法求连续背包问题

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

二、实验原理: 贪心算法原理:在贪婪算法(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背包问题

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

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

matlab中贪婪算法求解背包问题的研究与应用

matlab中贪婪算法求解背包问题的研究与应用

matlab中贪婪算法求解背包问题的研究与应用背包问题是一个经典的组合优化问题,在各个领域都有广泛的应用。

解决背包问题的方法有很多种,其中贪婪算法是一种常用且高效的方法。

贪婪算法是一种属于启发式算法的解题方法,通过每一步选择当前状态下最优的选择,然后逐步构建最终解。

贪婪算法具有简单、高效、容易实现等特点,适用于大规模问题的求解。

背包问题可以分为0-1背包问题和分数背包问题。

0-1背包问题的特点是每个物品要么完整地放入背包,要么完整地不放入背包;而分数背包问题则允许物品被部分地放入背包。

贪婪算法在解决背包问题时,可以根据不同的目标函数来选择最优解。

例如,在0-1背包问题中,可以选择物品的价值最高或者重量最小作为目标函数。

在分数背包问题中,则可以选择物品的单位价值最高作为目标函数。

在研究方面,贪婪算法在背包问题中的应用已经得到了广泛的研究。

研究者一方面致力于改进贪婪算法的效率和精度,另一方面也结合其他优化方法,如动态规划、遗传算法等进行混合优化。

贪婪算法在背包问题的应用也非常广泛。

例如,在电子商务领域,背包问题可以用来对物品进行优先级排序,以便更好地满足用户的需求。

在资源分配问题中,贪婪算法可以用来计算最优的资源分配方案。

在物流领域,贪婪算法可以用来优化货物的装载方案。

虽然贪婪算法具有高效、简单的特点,但是它并不一定能求出最优解。

这是因为贪婪算法在每一步只能看到局部最优解,而不能保证全局最优解。

因此,在实际应用中,需要根据具体问题的特点选择合适的算法,并进行适当的调整和改进。

总之,贪婪算法是一种常用且高效的方法,在解决背包问题以及其他组合优化问题时都有广泛的应用。

研究者们通过改进算法的效率和精度,并结合其他优化方法进行混合优化,使得贪婪算法在实际问题中发挥出更大的作用。

贪心法解决背包问题

贪心法解决背包问题

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

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

c语言算法--贪婪算法---01背包问题

c语言算法--贪婪算法---01背包问题

c语言算法--贪婪算法---0/1背包问题在0 / 1背包问题中,需对容量为c 的背包进行装载。

从n 个物品中选取装入背包的物品,每件物品i 的重量为wi ,价值为pi 。

对于可行的背包装载,背包中物品的总重量不能超过背包的容量,最佳装载是指所装入的物品价值最高,即n ?i=1pi xi 取得最大值。

约束条件为n ?i =1wi xi≤c 和xi?[ 0 , 1 ] ( 1≤i≤n)。

在这个表达式中,需求出xt 的值。

xi = 1表示物品i 装入背包中,xi =0 表示物品i 不装入背包。

0 / 1背包问题是一个一般化的货箱装载问题,即每个货箱所获得的价值不同。

货箱装载问题转化为背包问题的形式为:船作为背包,货箱作为可装入背包的物品。

例1-8 在杂货店比赛中你获得了第一名,奖品是一车免费杂货。

店中有n 种不同的货物。

规则规定从每种货物中最多只能拿一件,车子的容量为c,物品i 需占用wi 的空间,价值为pi 。

你的目标是使车中装载的物品价值最大。

当然,所装货物不能超过车的容量,且同一种物品不得拿走多件。

这个问题可仿照0 / 1背包问题进行建模,其中车对应于背包,货物对应于物品。

0 / 1背包问题有好几种贪婪策略,每个贪婪策略都采用多步过程来完成背包的装入。

在每一步过程中利用贪婪准则选择一个物品装入背包。

一种贪婪准则为:从剩余的物品中,选出可以装入背包的价值最大的物品,利用这种规则,价值最大的物品首先被装入(假设有足够容量),然后是下一个价值最大的物品,如此继续下去。

这种策略不能保证得到最优解。

例如,考虑n=2, w=[100,10,10], p =[20,15,15], c = 1 0 5。

当利用价值贪婪准则时,获得的解为x= [ 1 , 0 , 0 ],这种方案的总价值为2 0。

而最优解为[ 0 , 1 , 1 ],其总价值为3 0。

另一种方案是重量贪婪准则是:从剩下的物品中选择可装入背包的重量最小的物品。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

算法设计与分析
第五章贪婪法的算法实现代码
1、算法1:贪婪法求解背包问题
#include<iostream>
using namespace std;
#define n 10
#define M 30
typedef struct
{
float p;//每个物体的价值
float w;//每个物体的重量
float v;//每个物体的价值重量比
}object;
void swap(object &x,object &y)
{
object t=x;
x=y;
y=t;
}
void bubble(object a[])
{
int i,j;
for(i=n-1;i>0;i--)
for(j=0;j<i;j++)
{
if(a[j].v<a[j+1].v)
swap(a[j],a[j+1]);
}
}
float f(object o[],float d,float x[])
{
int i,j;
for(i=0;i<n;i++)
{
o[i].v=o[i].p/o[i].w;
x[i]=0;
}
float m=M;
bubble(o);
for(int i=0;i<n;i++)
{
cout<<"物体的价值比重是:"<<o[i].v<<"\t";
if((i+1)%2==0)
cout<<endl;
}
for(int j=0;j<n;j++)
{
if(o[j].w<=m)
{
d=d+o[j].p;
m=m-o[j].w;
x[j]=1;
}
else
{
x[j]=m/o[j].w;
d+=x[j]*o[j].p;
break;
}
}
return d;
}
void main()
{
object o[n];
float a[]={3,4,2,5,7,10,1,6,9,8};
float b[]={7,6,6,8,12,15,4,10,14,13};
for(int i=0;i<n;i++)
{
o[i].w=a[i];
o[i].p=b[i];
}
float d=0;
float x[n];
d=f(o,d,x);
cout<<"最优值为:"<<d<<endl;
for(int i=0;i<n;i++)
cout<<"物体的比重为:"<<"x["<<i<<"]="<<x[i]<<"\n";
system("pause");
}。

相关文档
最新文档