背包问题的贪心算法

合集下载

贪心算法之背包问题

贪心算法之背包问题

贪⼼算法之背包问题问题描述:给定n种物品,1个背包,背包容量为c,每个物品i的价值为vi,重量为wi,如何选择装⼊物品能使背包的总价值最⼤?注意:与0-1背包问题不同,在选择物品i装⼊背包时,可以选择物品i的⼀部分,⽽不⼀定要全部装⼊背包,1<=i<=n形式化描述:给定c >0, wi >0, vi >0 , 1≤i≤n.要求找⼀n元向量A=(x1,x2,…,xn), 0<=xi<=1【0~1表⽰取物品的某⼀部分】,1<=i<=n,使得 ∑wixi≤c【物品的重量和⼩于背包总容量】⽽且∑ vixi达到最⼤。

算法思路:将物品按照单位重量价值进⾏排序(从⼤到⼩),将尽可能多的单位重量价值最⾼的物品装⼊背包,若将这种物品全部装⼊背包后,背包还有多余容量,则选择单位重量价值次⾼的并尽可能多地装⼊背包。

如果最后⼀件物品⽆法全部装⼊,则计算可以装⼊的⽐例,然后按⽐例装⼊。

代码实现:数据结构:结构体1 #include <iostream>2 #include <algorithm>3using namespace std;4struct item{5int weight;//物品的重量6int value;//物品的价值7float bi;//物品单位重量的价值8float rate;//使⽤率:1代表物品完整放⼊,⼩于1代表被分割后放⼊9 }items[100];10bool cmp(const item &a,const item &b){11return a.bi>b.bi;12 }13int main(){14int n;//n件物品15float c;//背包容量为c16 cout<<"输⼊物品件数和背包容量:"<<endl;17 cin>>n>>c;18 cout<<"依次输⼊每件物品的价值和重量:"<<endl;19float v[n],w[n];//v[n]:n件物品的价值,w[n]:n件商品的重量20for(int i=0;i<n;i++){21 cin>>items[i].value>>items[i].weight;22 items[i].bi=items[i].value/items[i].weight;//计算单位重量价值23 items[i].rate=0;//初始化每件物品的使⽤率24 }25 sort(items,items+n,cmp);//按照单位重量的价值排序26int sum=0,j=0;27for(j=0;j<n;j++){28if(items[j].weight<=c){//选择单位价值重量最⼤的并且不超过背包容量的29 items[j].rate=1;30 sum+=items[j].weight;31 c-=items[j].weight;32 cout<<"重:"<<items[j].weight<<"、价值:"<<items[j].value<<"的物品被放⼊了背包"<<endl<<"放⼊⽐例:"<<items[j].rate<<endl;33 }34else break;35 }36if(j<n){//物品未装完37 items[j].rate=c/items[j].weight;//背包容量还剩c,计算出未装⼊的物品能装多少的⽐例38 sum+=items[j].rate*items[j].weight;//加上装⼊部分⽐例物品的重量39 cout<<"重:"<<items[j].weight<<"、价值:"<<items[j].value<<"被放⼊了背包"<<endl<<"放⼊⽐例:"<<items[j].rate<<endl;40 }41return0;424344 }。

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

贪心算法补充背包问题

贪心算法补充背包问题

void Insertionsort(goodinfo goods[],int n) {//插入排序,按pi/wi价值收益进行排序,一般教材 {//插入排序 插入排序, pi/wi价值收益进行排序 价值收益进行排序, 上按冒泡排序 int j,i; for(j=2;j<=n;j++) { goods[0]=goods[j]; i=j-1; i=jwhile (goods[0].p>goods[i].p) { goods[i+1]=goods[i]; i--; --; } goods[i+1]=goods[0]; } }//按物品效益,重量比值做升序排列 }//按物品效益 按物品效益,
引言
顾名思义,贪心算法总是作出在当前看来 顾名思义,贪心算法总是作出在当前看来 最好的选择。也就是说贪心算法并不从整 体最优考虑,它所作出的选择只是在某种 意义上的局部最优选择。当然,希望贪心 意义上的局部最优选择。当然,希望贪心 算法得到的最终结果也是整体最优的。虽 然贪心算法不能对所有问题都得到整体最 优解,但对许多问题它能产生整体最优解。 如单源最短路经问题,最小生成树问题等。 在一些情况下,即使贪心算法不能得到整 体最优解,其最终结果却是最优解的很好 近似。
Hale Waihona Puke 贪心算法解决背包问题的算法实现: 贪心算法解决背包问题的算法实现:
#include <iostream.h> struct goodinfo { float p; //物品效益 float w; //物品重量 float X; //物品该放的 数量 int flag; //物品编号 };//物品信息结构体
贪心算法解决背包问题有几种策略: 贪心算法解决背包问题有几种策略: (i) 一种贪婪准则为:从剩余的物品中,选出可以装入背包的价值最 大的物品,利用这种规则,价值最大的物品首先被装入(假设有足够 容量),然后是下一个价值最大的物品,如此继续下去。这种策略不 能保证得到最优解。例如,考虑n=2, w=[100,10,10], p =[20,15,15], 能保证得到最优解。例如,考虑n=2, c = 105。当利用价值贪婪准则时,获得的解为x= [ 1 , 0 , 0 ],这 105。当利用价值贪婪准则时,获得的解为x= ],这 种方案的总价值为2 0。而最优解为[ 种方案的总价值为2 0。而最优解为[ 0 , 1 , 1 ],其总价值为3 0。 ],其总价值为3 0。 (ii) 另一种方案是重量贪婪准则是:从剩下的物品中选择可装入背包 的重量最小的物品。虽然这种规则对于前面的例子能产生最优解,但 在一般情况下则不一定能得到最优解。考虑n= 在一般情况下则不一定能得到最优解。考虑n= 2 ,w=[10,20], p=[5,100], c= 2 5。当利用重量贪婪策略时,获得的解为x =[1,0], 5。当利用重量贪婪策略时,获得的解为x 比最优解[ 比最优解[ 0 , 1 ]要差。 ]要差。 (iii) 还有一种贪婪准则,就是我们教材上提到的,认为,每一项计 算yi=vi/si,即该项值和大小的比,再按比值的降序来排序,从第一项 yi=vi/si,即该项值和大小的比,再按比值的降序来排序,从第一项 开始装背包,然后是第二项,依次类推,尽可能的多放,直到装满背 包。 有的参考资料也称为价值密度pi/wi贪婪算法。这种策略也不能保证得 有的参考资料也称为价值密度pi/wi贪婪算法。这种策略也不能保证得 到最优解。利用此策略试解n= 到最优解。利用此策略试解n= 3 ,w=[20,15,15], p=[40,25,25], c=30 时的最优解。虽然按pi /wi 非递(增)减的次序装入物品不能 时的最优解。虽然按pi 保证得到最优解,但它是一个直觉上近似的解。 而且这是解决普通背包问题的最优解,因为在选择物品i 而且这是解决普通背包问题的最优解,因为在选择物品i装入背包时, 可以选择物品i的一部分,而不一定要全部装入背包,1≤i≤n。 可以选择物品i的一部分,而不一定要全部装入背包,1≤i≤n。

经典贪心题

经典贪心题

贪心算法是一种在解决问题的过程中追求局部最优的算法,对于一个有多种属性的事物来说,贪心算法会优先满足某种条件,追求局部最优的同时希望达到整体最优的效果。

以下是一些经典的贪心算法问题:1. 背包问题:给定一组物品,每个物品都有自己的重量和价值,背包的总容量有限。

贪心算法需要选择物品以最大化背包中物品的总价值,同时不超过背包的总容量。

这种问题可以有多种变体,例如分数背包问题和完全背包问题。

2. 硬币找零问题:给定一组硬币的面值和数量,以及需要找零的金额。

贪心算法需要选择硬币以最小化找零的总数量。

这个问题可以通过从大到小排序硬币,并从最大面值的硬币开始选择,直到找零的金额达到所需的总金额。

3. 区间选点问题:给定一系列闭区间,每个闭区间都有一个起始点和结束点。

贪心算法需要选择尽量少的点,使得每个闭区间内至少有一个点被选中。

这个问题可以通过对结束点进行排序,并从左到右选择结束点,直到下一个要选择的结束点与上一个选择的结束点之间的距离大于当前选择的结束点与上一个选择的结束点之间的距离为止。

4. 区间覆盖问题:给定一系列闭区间,贪心算法需要选择尽量少的区间,使得所有区间都被覆盖。

这个问题可以通过对每个闭区间的左端点进行排序,并从左到右选择左端点,直到下一个要选择的左端点与上一个选择的左端点之间的距离大于当前选择的左端点与上一个选择的左端点之间的距离为止。

5. 排班问题:给定一组员工和他们的班次需求,以及一组工作日的日程安排。

贪心算法需要为员工分配班次,以最小化总工作时间并满足所有工作日的需求。

这个问题可以通过从可用的班次中选择最长的班次,并从左到右分配员工,直到所有员工都被分配到一个班次为止。

这些问题是贪心算法的经典示例,它们展示了贪心算法在解决优化问题中的广泛应用。

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

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

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

背包问题的贪心算法

背包问题的贪心算法

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 >后者

算法背包问题的五种方法

算法背包问题的五种方法

算法背包问题的五种方法1. 动态规划背包问题是一种经典的组合优化问题,动态规划是解决背包问题的常用方法之一。

动态规划将问题分解为子问题,并利用已解决子问题的结果来求解更大规模的问题。

对于背包问题,动态规划算法的基本思想是创建一个二维数组dp,其中dp[i][j]表示在前i个物品中选择若干个物品放入容量为j的背包中所能获得的最大价值。

通过填表格的方式,从子问题逐步求解到原问题,最终得到最优解。

2. 贪心算法贪心算法是另一种解决背包问题的方法。

它的基本思想是每一步都选择当前看起来最好的选择,而不考虑之前的选择对后续步骤的影响。

在背包问题中,贪心算法通常是按照物品的价值密度(价值与重量的比值)进行排序,然后依次选择价值密度最高的物品放入背包,直到背包容量不足为止。

贪心算法的优势在于其简单性和高效性,但它并不一定能得到最优解。

3. 分支定界法分支定界法是一种通过搜索方式求解背包问题的方法。

它的基本思想是通过搜索可能的解空间,并根据当前搜索路径的特性进行剪枝操作,从而减少搜索的时间和空间复杂度。

在背包问题中,分支定界法通常根据当前节点的上界(通过松弛问题得到)与当前最优解进行比较,如果上界小于当前最优解,则该节点不再继续拓展,从而减少搜索空间的大小,提高求解效率。

4. 回溯算法回溯算法是一种通过不断试探和回退的方式求解背包问题的方法。

它的基本思想是从问题的初始状态开始,不断地尝试不同的决策,并根据约束条件判断该决策是否可行。

如果决策可行,则继续尝试下一步决策;如果不可行,则回退到上一步并尝试其他决策。

在背包问题中,回溯算法通过递归的方式依次尝试每个物品的放入与不放入两种选择,直到找到满足约束条件的解或者穷尽所有可能。

5. 近似算法近似算法是一种通过快速求解背包问题的“近似”解来减小计算复杂度的方法。

它的基本思想是用一种简单而快速的策略求解背包问题,并且能够保证求解结果的近似程度。

在背包问题中,常见的近似算法有贪心算法和启发式算法。

背包问题的贪心算法

背包问题的贪心算法

背包问题的贪心算法(总8页) -CAL-FENGHAI.-(YICAI)-Company One1-CAL-本页仅作为文档封面,使用请直接删除贪心方法:总是对当前的问题作最好的选择,也就是局部寻优。

最后得到整体最优。

应用:1:该问题可以通过“局部寻优”逐步过渡到“整体最优”。

贪心选择性质与“动态规划”的主要差别。

2:最优子结构性质:某个问题的整体最优解包含了“子”问题的最优解。

代码如下:#include <>struct goodinfo{float p; >goods[i].p) { goods[i+1]=goods[i]; i--; } goods [i+1]=goods[0]; }}=0;cu=M; >cu)=1;cu=cu-goods[i].w;=cu/goods[i].w;lag<goods[i].flag){goods[i+1]=goods[i];i--;}goods[i+1]=goods[0];}<<endl; }}void main(){cout<<"|--------运用贪心法解背包问题---------|"<<endl;cout<<"|---power by zhanjiantao(0)---|"<<endl;cout<<"|-------------------------------------|"<<endl;int j;int n;float M;goodinfo *goods;lag=i; cout<<"请输入第"<<i<<"件物品的重量:"; cin>>g oods[i].w; cout<<"请输入第"<<i<<"件物品的效益:"; cin>>goods[i].p; goods[i].p=goods[i].p/goods[i].w;//得出物品的效益,重量比cout<<en dl; }Insertionsort(goods,n); bag(goods,M,n); cout<<"press <1> to run agian"<<end l; cout<<"press <0> to exit"<<endl; cin>>j; }}#include<>#include<>#define Max 100/*定义栈结构*/typedef struct list{ int data[Max]; int top;}Seqstack; /*定义一个用来存储结果的链表*/typedef struct List{ Seqstack result; struct List * Next;}Seqlist,*Pointer;void Inicial_List(Pointer p){ p=(Pointer)malloc(sizeof(Seqlist));p->Next=NULL;}Seqstack Push_Stack(int n,Seqstack s){ ++;[]=n;return s;}int Add_Stack(Seqstack s){Int total=0,i;if>=0){ for(i=0;i<=;i++)total+=[i];}else{ total=0; }return total;}Seqstack Pop_Stack(Seqstack s){printf("%d",[]);if>=0);return s;}/*执行回溯操作的函数*//*参数说明:n->数的总的个数,a[]用来存放数的数组,k查找的总体积*/Pointer Query_Result(int n,int b[],int k){ int i,j;Seqstack mystack;Seqlist *newnode;Pointer r,p=NULL;Inicial_List(p);r=p; for(i=0;i<n;i++){ =-1;j=i;while(j<n){if(Add_Stack(mystack)+b[j]<k){ mystack=Push_Stack(b[j],mystack);j++; }else if(Add_Stack(mystack)+b[j]==k){ mystack=Push_Stack(b[j],mystack);newnode=(Pointer)malloc(sizeof(Seqlist));newnode->result=mystack;newnode->Next=NULL;r->Next=newnode;r=newnode;mystack=Pop_Stack(mystack);j++;}else if(Add_Stack(mystack)+b[j]>k){}}}return p;}void Print_List(Pointer p){int i,j=0;p=p->Next;printf("welcome the outer\n");if(p==NULL)printf("there no results\n");while(p!=NULL){j++;printf("the %d result is: ",j);for(i=0;i<=p->;i++){ printf(" %d",p->[i]);}p=p->Next;printf("\n"); }printf("\n");}void Sort_Array(int b[],int n){int i,j,temp;for(i=0;i<n;i++){ for(j=0;j<n-i;j++){ if(b[j]<b[j+1]){ temp=b[j];b[j]=b[j+1];b[j+1]=temp;}}}}void main(){int i,n,k,select,a[Max];Pointer head;printf("******************************************\n"); printf ("1 start\n2 exit\n");scanf("%d",&select);while(select==1)printf("please input the total products\n");scanf("%d",&n);printf("please input the volumn of n products\n");for(i=0;i<n;i++){printf("please input the %d integers",i+1);scanf("%d",&a[i]);}printf("\n");printf("please input the volunm to put\n");scanf("%d",&k);Sort_Array(a,n);head=Query_Result(n,a,k);Print_List(head);printf("******************************************\n");printf("1 start\n2 exit\n"); scanf("%d",&select);}}#include<>#include<>#define Max 100/*定义栈结构*/typedef struct list{ int data[Max]; int top;}Seqstack; /*定义一个用来存储结果的链表*/typedef struct List{Seqstack result;struct List * Next;}Seqlist,*Pointer;void Inicial_List(Pointer p){p=(Pointer)malloc(sizeof(Seqlist));p->Next=NULL;}Seqstack Push_Stack(int n,Seqstack s){ ++;[]=n;return s;}int Add_Stack(Seqstack s){ int total=0,i;if>=0){for(i=0;i<=;i++)total+=[i];}else{total=0;}return total;}Seqstack Pop_Stack(Seqstack s){printf("%d",[]);if>=0); return s;}/*执行回溯操作的函数*//*参数说明:n->数的总的个数,a[]用来存放数的数组,k查找的总体积*/Pointer Query_Result(int n,int b[],int k){int i,j;Seqstack mystack;Seqlist *newnode;Pointer r,p=NULL;Inicial_List(p);r=p;for(i=0;i<n;i++){=-1;j=i;while(j<n){if(Add_Stack(mystack)+b[j]<k){mystack=Push_Stack(b[j],mystack);j++;}else if(Add_Stack(mystack)+b[j]==k){mystack=Push_Stack(b[j],mystack);newnode=(Pointer)malloc(sizeof(Seqlist)); newnode->result=mystack;newnode->Next=NULL;r->Next=newnode;r=newnode;mystack=Pop_Stack(mystack);j++;}else if(Add_Stack(mystack)+b[j]>k){j++;}}}return p;}void Print_List(Pointer p){int i,j=0;p=p->Next;printf("welcome the outer\n");if(p==NULL)printf("there no results\n");while(p!=NULL){j++;printf("the %d result is: ",j);for(i=0;i<=p->;i++){printf(" %d",p->[i]);}p=p->Next;printf("\n");}printf("\n");}void Sort_Array(int b[],int n){int i,j,temp;for(i=0;i<n;i++) { for(j=0;j<n-i;j++){if(b[j]<b[j+1]){temp=b[j];b[j]=b[j+1];b[j+1]=temp;}}}}void main(){int i,n,k,select,a[Max]; Pointer head;printf("******************************************\n"); printf("1 start\n2 exit\n"); scanf("%d",&select);while(select==1){printf("please input the total products\n");scanf("%d",&n);printf("please input the volumn of n products\n");for(i=0;i<n;i++){printf("please input the %d integers",i+1);scanf("%d",&a[i]); } printf("\n");printf("please input the volunm to put\n");scanf("%d",&k); Sort_Array(a,n);head=Query_Result(n,a,k);Print_List(head);printf("******************************************\n"); printf("1 start\n2 exit\n");scanf("%d",&select);}}。

贪心算法与背包问题的求解策略

贪心算法与背包问题的求解策略

贪心算法与背包问题的求解策略贪心算法是一种常用的优化算法,特别适用于一些具有最优子结构性质的问题。

而背包问题是一个经典的组合优化问题,它涉及到在限定容量下如何选择物品,使得总价值最大化。

本文将探讨贪心算法在背包问题求解中的应用策略。

一、背包问题的定义与分类背包问题是在给定容量的背包和一组物品的情况下,如何选择物品放入背包中,使得物品的总价值最大化。

背包问题可以分为0-1背包问题、分数背包问题和多重背包问题三种。

1. 0-1背包问题:每种物品只能选择放入背包一次或者不放入。

目标是使得背包中物品价值最大化。

2. 分数背包问题:物品可以分割成较小的部分放入背包,即可以选择部分物品放入。

目标是使得背包中物品价值最大化。

3. 多重背包问题:物品有多个可选的数量限制,每种物品可以选择放入多次但不能超过其数量限制。

目标是使得背包中物品价值最大化。

二、贪心算法在背包问题求解中的应用策略在求解背包问题时,贪心算法通常采取以下两种策略:1. 价值密度优先策略:对于0-1背包问题和分数背包问题,贪心算法可以根据物品的单位价值(价值与重量的比率)进行排序,然后按照价值密度从大到小的顺序选择物品放入背包。

这样可以保证每次选择的物品是当前局部最优解,进而得到全局最优解。

算法步骤如下:a) 计算每种物品的单位价值。

b) 对物品按照单位价值进行排序。

c) 从价值最大的物品开始,依次尝试放入背包直至放满或无法继续放入。

2. 数量优先策略:对于多重背包问题,贪心算法可以根据物品的剩余数量进行排序,优先选择剩余数量最多的物品。

这样可以尽可能多地选择该物品,以使总价值最大化。

算法步骤如下:a) 对物品按照剩余数量进行排序。

b) 从剩余数量最多的物品开始,依次尝试放入背包直至放满或无法继续放入。

值得注意的是,贪心算法在某些情况下可能无法得到最优解。

对于一些特殊的背包问题,如存在约束条件或物品具有特殊属性时,贪心算法可能会得出次优解或错误解。

贪心算法之背包问题

贪心算法之背包问题

贪⼼算法之背包问题贪⼼算法(⼜称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。

也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。

贪⼼算法不是对所有问题都能得到整体最优解,关键是贪⼼策略的选择,选择的贪⼼策略必须具备⽆后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。

完全背包问题:给定n个物品和⼀个容量为C的背包,物品i的重量是Wi,其价值为Vi,背包问题是如何选择⼊背包的物品,使得装⼊背包的物品的总价值最⼤,与0-1背包的区别是,在完全背包问题中,可以将物品的⼀部分装⼊背包,但不能重复装⼊。

设计算法的思路很简单,计算物品的单位价值,然后尽可能多的将单位重量价值⾼的物品放⼊背包中。

python实现代码如下:1# coding=gbk2# 完全背包问题,贪⼼算法3import time4__author__ = 'ice'567class goods:8def__init__(self, goods_id, weight=0, value=0):9 self.id = goods_id10 self.weight = weight11 self.value = value121314# 不适⽤于0-1背包15def knapsack(capacity=0, goods_set=[]):16# 按单位价值量排序17 goods_set.sort(key=lambda obj: obj.value / obj.weight, reverse=True)18 result = []19for a_goods in goods_set:20if capacity < a_goods.weight:21break22 result.append(a_goods)23 capacity -= a_goods.weight24if len(result) < len(goods_set) and capacity != 0:25 result.append(goods(a_goods.id, capacity, a_goods.value * capacity / a_goods.weight))26return result272829 some_goods = [goods(0, 2, 4), goods(1, 8, 6), goods(2, 5, 3), goods(3, 2, 8), goods(4, 1, 2)]3031 start_time = time.clock()32 res = knapsack(6, some_goods)33 end_time = time.clock()34print('花费时间:' + str(end_time - start_time))3536for obj in res:37print('物品编号:' + str(obj.id) + ' ,放⼊重量:' + str(obj.weight) + ',放⼊的价值:' + str(obj.value), end=',')38print('单位价值量为:' + str(obj.value / obj.weight))394041# 花费时间:2.2807240614677942e-0542# 物品编号:3 ,放⼊重量:2,放⼊的价值:8,单位价值量为:4.043# 物品编号:0 ,放⼊重量:2,放⼊的价值:4,单位价值量为:2.044# 物品编号:4 ,放⼊重量:1,放⼊的价值:2,单位价值量为:2.045# 物品编号:1 ,放⼊重量:1,放⼊的价值:0.75,单位价值量为:0.75。

部分背包问题的贪心算法正确性证明

部分背包问题的贪心算法正确性证明

部分背包问题的贪⼼算法正确性证明⼀,部分背包问题介绍⾸先介绍下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。

贪心法求解背包问题

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

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

基于朴素贪心算法的背包问题解决方案

基于朴素贪心算法的背包问题解决方案

基于朴素贪心算法的背包问题解决方案背包问题是一类经典的组合优化问题,它的一般形式描述为:有一个固定大小的背包,和一些物品,每个物品都有自己的价值和大小,需要选出一些物品装入背包中,使得装进去的物品价值最大化,同时又不能超出背包容量的限制。

这个问题在实际生活中有很多应用,比如在货物的装载和运输、在零售商的库存管理、在网页推荐系统等等。

解决背包问题的方法有很多,其中比较经典的是基于动态规划的解法,但是这种解法需要使用大量的存储空间,如果物品数量很大的话,计算复杂度也会很高。

因此本文将介绍一种基于朴素贪心算法的背包问题解决方案。

一、背包问题的数学模型在介绍具体的解决方案之前,我们需要先来看一下背包问题的数学模型。

假设我们有n个物品,第i个物品的重量为wi,价值为vi,背包的容量为W。

那么背包问题可以用下面的数学模型来描述:$$\begin{aligned}&\max\sum_{i=1}^{n}v_ix_i\\&s.t.\sum_{i=1}^ {n}w_ix_i\leq W\\&x_i\in \{0,1\}\end{aligned}$$其中,$x_i$表示第$i$个物品是否被选中,$v_i$和$w_i$分别表示第$i$个物品的价值和重量。

第一个约束条件表示所有选中的物品的总重量不能超过背包的容量$W$,第二个约束条件表示每个物品最多只能选一次。

二、基于朴素贪心算法的解法朴素贪心算法的思路很简单:每次选择可行的物品中价值最大的那一个,直到不能再选为止。

对于背包问题来说,我们可以按照物品的单位价值(即价值与重量比值)从大到小排序,然后依次选择可行的物品加入背包中。

具体步骤如下:1. 计算每个物品的单位价值,按照单位价值从大到小排序。

2. 依次加入可行的物品,直到不能再加入为止。

3. 最后得到的物品组合就是背包问题的最优解。

该算法的时间复杂度为$O(nlogn)$,其中$n$为物品的数量。

背包问题的解决算法

背包问题的解决算法

背包问题的解决算法在日常生活中,我们常常会遇到背包问题。

比如说,你需要出门远足,但是又不想背太多的东西,怎么办?这时候,你就需要一种背包算法,用以帮助你选出最好的装备。

当然,背包算法不仅仅局限于这种场景,还可以应用于计算机科学等领域。

背包问题可以定义为:在限定容量下,找到能够装下最大价值物品的选择方案。

在计算机科学中,背包问题又分为0/1背包和无限背包两种类型。

0/1背包指的是在数量有限的情况下,每种物品只能选择一次;无限背包则意味着每种物品可以重复选择。

现在,我们来讨论一下几种常见的背包算法。

1. 贪心算法贪心算法是一种常见的解决背包问题的方法。

首先,根据每个物品的价值大小来求解。

然后,将每个物品按照其价值排序。

按照顺序,从价值最高的开始选择,在能够装下的情况下,尽量选择多的物品。

这种方法容易理解,但是它并不一定能够获得最优解。

2. 动态规划算法动态规划是解决背包问题最常用的算法。

它将问题分解成多个子问题,并且利用已经求解过的子问题来递推求解更大的问题。

具体来说,动态规划算法需要在每个状态中维护当前已经选择的物品,以及它们的价值和总重量。

然后,根据每个物品的价值,计算出在当前重量下选择这个物品的最大价值,同时比较这个价值和不选择这个物品的价值大小,最终得出最优解。

3. 回溯算法回溯算法也是一种解决背包问题的方法。

它的基本思想是,从初始状态开始,考虑每种可能的选择,最终找到最优解。

相比其他算法,回溯算法需要考虑所有可能的解,因此在问题较大的时候,它的时间复杂度可能较高。

但是,回溯算法通常能够得到最优解。

4. 分支定界算法分支定界算法也是一种解决背包问题的方法。

它通过确定每种物品能否被选择,来缩小解空间并加速搜索。

具体来说,它会根据价值和重量来对物品进行排序,并尝试从价值最高的物品开始选择。

然后,将剩余的物品按选择顺序进行排序,并对每个物品进行深度优先搜索,直到搜索到了可行解或者不可行解为止。

在实际应用中,以上几种算法都有其优缺点。

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

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

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

贪心算法与背包问题的求解策略

贪心算法与背包问题的求解策略

贪心算法与背包问题的求解策略贪心算法(Greedy Algorithm)是一种常用的算法策略,用于求解最优化问题。

背包问题(Knapsack Problem)则是一个经典的组合优化问题,涉及在限制条件下如何选择物品以最大化价值。

本文将探讨贪心算法在解决背包问题时的应用与求解策略。

一、背包问题简介背包问题是一个常见的动态规划问题,其基本形式为:有一个背包,容量为C(常为非负整数),有n个物品,每个物品的重量为w[i],价值为v[i]。

现在需要从这些物品中选择一部分装入背包,使得在满足背包容量的限制下,所装入物品的总价值最大化。

二、贪心算法的基本思想贪心算法的基本思想是,每一步都选择当前情况下的最优解,希望通过每一步的最优解最终达到全局最优解。

然而,贪心算法并不是适用于所有问题的通用解决方法,它适用于一些特定的问题,如背包问题。

三、贪心算法在背包问题中的应用在背包问题中,常见的贪心策略有两种:按价值密度排序和按重量排序。

下面将分别介绍这两种贪心策略的具体应用。

1. 按价值密度排序按价值密度排序是指将物品按照单位重量的价值从大到小进行排序。

具体操作步骤如下:(1)计算每个物品的价值密度,即v[i]/w[i]。

(2)按照价值密度从大到小的顺序对物品进行排序。

(3)从价值密度最高的物品开始,依次将物品放入背包,直至背包容量达到上限或无物品可放。

2. 按重量排序按重量排序是指将物品按照重量从小到大进行排序。

具体操作步骤如下:(1)按照物品的重量从小到大进行排序。

(2)从重量最小的物品开始,依次将物品放入背包,直至背包容量达到上限或无物品可放。

四、贪心算法的优缺点贪心算法相比其他算法具有简单、高效的特点。

然而,贪心算法并不是万能的,它在某些情况下可能无法得到最优解。

例如,在背包问题中,贪心算法按照价值密度排序的策略并不能保证一定能得到最优解,因为可能存在某些物品的价值密度很高,但重量也很大,无法放入背包。

五、贪心算法的应用场景贪心算法常被应用于一些特定的问题领域,如最小生成树、调度问题、图着色等。

背包问题贪心法和动态规划方案法求解

背包问题贪心法和动态规划方案法求解

背包问题贪心法和动态规划方案法求解嘿,大家好!今天咱们来聊聊那个让人又爱又恨的背包问题。

这个问题可是算法领域的经典难题,不过别怕,今天我会用贪心法和动态规划两种方法帮你轻松搞定它!来个简单直接的背景介绍。

背包问题,简单来说,就是给定一组物品,每个物品都有一定的价值和重量,你需要在不超过背包承载重量的前提下,挑选出价值最大的物品组合。

听起来是不是有点像生活中的购物决策?哈哈,没错,这就是背包问题的魅力所在。

好,下面咱们直接进入主题。

一、贪心法贪心法,顾名思义,就是每一步都选择当前看起来最优的方案。

对于背包问题,贪心法的核心思想就是:每次都选取价值密度最大的物品。

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、 贪心选择方法:我们根据输入的序列构造一个新的序列:P1/W1, P2/W2, …, Pn/Wn;这序 列表示的含义是每件物品单位重量的价值;我们对这个序列进行从大到小排序,按照这 个排序进行选择物品装入包中, 直到包装满为止, 对于最后一件物品可能不能完全装入, 只能装入一部分。 2、 贪心选择性证明:假设序列 P1/W1, P2/W2, …, Pn/Wn 从大到小排序后的第一个值的下标为 k, 表示物品 k 的单位重量的价值最大, 那么我们要证明的是存在一个最优解 A 包含 Xk, 并且若 M≥Wk,则 Xk=1;否则 Xk=M/Wk。 证明:假设 B 是问题的一个最优解,如果 B 包含 Xk,且满足“若 M≥Wk,则 Xk=1;否 则 Xk=M/Wk” ,那么令 A=B,B 就是我们所要寻找的最优解,问题得证。否则,如果 B 中 不包含 Xk 或者是如果 B 包含 Xk 但是不满足“若 M≥Wk,则 Xk=1;否则 Xk=M/Wk” ,可 能是当 M≥Wk 时 Xk<1;或者当 M<Wk 时 Xk< M/Wk。无论何种情况,我们用 H 表示满足 条件“若 M≥Wk,则 Xk=1;否则 Xk=M/Wk”时的 Xk 的取值。用 V(A),V(B)分别表示问题 解为 A 和 B 时的包中物品的价值总和。我们这样来通过 B 构造 A:从 B 的解的包中,任 意取出重为 H*Wk 的物品(这些物品可能是一种,也可能是多种),假设其价值为 V’,包 中剩下的物品价值为 V’’(即 V(B)=V’+V’’),我们再把百分比为 H 的物品 k 装入背包中,这 样构成解 A,下面我们证明 A 是最优解。V(A)=V’’+H*Pk,V(B)=V’+V’’,因为(Pk/Wk)是所 有物品中的最大值,所以在重量均为 H*Wk 的情况下,(Pk/Wk)*( H*Wk)= H*Pk≥V’,所以 V(A)≥V(B);又因为 B 是最优解,所以 V(B)≥V(A)。综上,有 V(A)=V(B),所以 A 也是最 优解,既而得证。 3、 最优子结构的证明: 原问题的解的形式为 Xi1, Xi2, Xi3, …, Xin; 子问题为从物品 S={i2, i3, …, in} 中选择物品,使得
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

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

最后得到整体最优。

应用:1:该问题可以通过“局部寻优”逐步过渡到“整体最优”。

贪心选择性质与“动态规划”的主要差别。

2:最优子结构性质:某个问题的整体最优解包含了“子”问题的最优解。

代码如下:#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;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<<"|---power by zhanjiantao(028054115)---|"<<endl; cout<<"|-------------------------------------|"<<endl;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;}}#include<stdio.h>#include<stdlib.h>#define Max 100/*定义栈结构*/typedef struct list{ int data[Max]; int top;}Seqstack; /*定义一个用来存储结果的链表*/typedef struct List{ Seqstack result; struct List * Next;}Seqlist,*Pointer;void Inicial_List(Pointer p){ p=(Pointer)malloc(sizeof(Seqlist));p->Next=NULL;}Seqstack Push_Stack(int n,Seqstack s){ s.top++;s.data[s.top]=n;return s;}int Add_Stack(Seqstack s){Int total=0,i;if(s.top>=0){ for(i=0;i<=s.top;i++)total+=s.data[i];}else{ total=0; }return total;}Seqstack Pop_Stack(Seqstack s){printf("%d",s.data[s.top]);if(s.top>=0)s.top--;return s;}/*执行回溯操作的函数*//*参数说明:n->数的总的个数,a[]用来存放数的数组,k 查找的总体积*/Pointer Query_Result(int n,int b[],int k){ int i,j;Seqstack mystack;Seqlist *newnode;Pointer r,p=NULL;Inicial_List(p);r=p; for(i=0;i<n;i++){ mystack.top=-1;j=i;while(j<n){if(Add_Stack(mystack)+b[j]<k){ mystack=Push_Stack(b[j],mystack);j++; }else if(Add_Stack(mystack)+b[j]==k) { mystack=Push_Stack(b[j],mystack);newnode=(Pointer)malloc(sizeof(Seqlist)); newnode->result=mystack;newnode->Next=NULL;r->Next=newnode;r=newnode;mystack=Pop_Stack(mystack);j++;}else if(Add_Stack(mystack)+b[j]>k){j++;}}}return p;}void Print_List(Pointer p){int i,j=0;p=p->Next;printf("welcome the outer\n");if(p==NULL)printf("there no results\n");while(p!=NULL){j++;printf("the %d result is: ",j);for(i=0;i<=p->result.top;i++){ printf(" %d",p->result.data[i]);}p=p->Next;printf("\n"); }printf("\n");}void Sort_Array(int b[],int n){int i,j,temp;for(i=0;i<n;i++){ for(j=0;j<n-i;j++){ if(b[j]<b[j+1]){ temp=b[j];b[j]=b[j+1];b[j+1]=temp;}}}}void main(){int i,n,k,select,a[Max];Pointer head;printf("******************************************\n"); printf("1 start\n2 exit\n"); scanf("%d",&select);while(select==1){printf("please input the total products\n");scanf("%d",&n);printf("please input the volumn of n products\n");for(i=0;i<n;i++){printf("please input the %d integers",i+1);scanf("%d",&a[i]);}printf("\n");printf("please input the volunm to put\n");scanf("%d",&k);Sort_Array(a,n);head=Query_Result(n,a,k);Print_List(head);printf("******************************************\n");printf("1 start\n2 exit\n"); scanf("%d",&select);}}#include<stdio.h>#include<stdlib.h>#define Max 100/*定义栈结构*/typedef struct list{ int data[Max]; int top;}Seqstack;/*定义一个用来存储结果的链表*/typedef struct List{Seqstack result;struct List * Next;}Seqlist,*Pointer;void Inicial_List(Pointer p){p=(Pointer)malloc(sizeof(Seqlist));p->Next=NULL;}Seqstack Push_Stack(int n,Seqstack s){ s.top++;s.data[s.top]=n;return s;}int Add_Stack(Seqstack s){ int total=0,i;if(s.top>=0){for(i=0;i<=s.top;i++)total+=s.data[i];}else{total=0;}return total;}Seqstack Pop_Stack(Seqstack s){printf("%d",s.data[s.top]);if(s.top>=0)s.top--; return s;}/*执行回溯操作的函数*//*参数说明:n->数的总的个数,a[]用来存放数的数组,k查找的总体积*/Pointer Query_Result(int n,int b[],int k){int i,j;Seqstack mystack;Seqlist *newnode;Pointer r,p=NULL;Inicial_List(p);r=p;for(i=0;i<n;i++){mystack.top=-1;j=i;while(j<n){if(Add_Stack(mystack)+b[j]<k){mystack=Push_Stack(b[j],mystack);j++;}else if(Add_Stack(mystack)+b[j]==k){mystack=Push_Stack(b[j],mystack);newnode=(Pointer)malloc(sizeof(Seqlist)); newnode->result=mystack;newnode->Next=NULL;r->Next=newnode;r=newnode;mystack=Pop_Stack(mystack);j++;}else if(Add_Stack(mystack)+b[j]>k){j++;}}}return p;}void Print_List(Pointer p){int i,j=0;p=p->Next;printf("welcome the outer\n");if(p==NULL)printf("there no results\n");while(p!=NULL){j++;printf("the %d result is: ",j);for(i=0;i<=p->result.top;i++){printf(" %d",p->result.data[i]);}p=p->Next;printf("\n");}printf("\n");}void Sort_Array(int b[],int n){int i,j,temp;for(i=0;i<n;i++) { for(j=0;j<n-i;j++){if(b[j]<b[j+1]){temp=b[j];b[j]=b[j+1];b[j+1]=temp;}}}}void main(){int i,n,k,select,a[Max]; Pointer head;printf("******************************************\n"); printf("1 start\n2 exit\n"); scanf("%d",&select);while(select==1){printf("please input the total products\n");scanf("%d",&n);printf("please input the volumn of n products\n");for(i=0;i<n;i++){printf("please input the %d integers",i+1);scanf("%d",&a[i]); } printf("\n");printf("please input the volunm to put\n");scanf("%d",&k); Sort_Array(a,n);head=Query_Result(n,a,k);Print_List(head);printf("******************************************\n"); printf("1 start\n2 exit\n");scanf("%d",&select);}}。

相关文档
最新文档