背包问题回溯法背包问题伪多项式算法是什么意思

背包问题回溯法  时间:2021-09-13  阅读:()

背包问题的算法

1)登上算法 用登山算法求解背包问题 function []=DengShan(n,G,P,W) %n是背包的个数,G是背包的总容量,P是价值向量,W是物体的重量向量 %n=3;G=20;P=[25,24,15];W2=[18,15,10];%输入量 W2=W; [Y,I]=sort(-P./W2);W1=[];X=[];X1=[]; for i=1:length(I) W1(i)=W2(I(i)); end W=W1; for i=1:n X(i)=0; RES=G;%背包的剩余容量 j=1; while W(j)<=RES X(j)=1; RES=RES-W(j); j=j+1; end X(j)=RES/W(j); end for i=1:length(I) X1(I(i))=X(i); end X=X1; disp('装包的方法是');disp(X);disp(X.*W2);disp('总的价值是:');disp(P*X'); 时间复杂度是非指数的 2)递归法 先看完全背包问题 一个旅行者有一个最多能用m公斤的背包,现在有n种物品,每件的重量分别是W1,W2,...,Wn, 每件的价值分别为C1,C2,...,Cn.若的每种物品的件数足够多. 求旅行者能获得的最大总价值。

本问题的数学模型如下: 设 f(x)表示重量不超过x公斤的最大价值, 则 f(x)=max{f(x-i)+c[i]} 当x>=w[i] 1<=i<=n 可使用递归法解决问题程序如下: program knapsack04; const maxm=200;maxn=30; type ar=array[0..maxn] of integer; var m,n,j,i,t:integer; c,w:ar; function f(x:integer):integer; var i,t,m:integer; begin if x=0 then f:=0 else begin t:=-1; for i:=1 to n do begin if x>=w[i] then m:=f(x-i)+c[i]; if m>t then t:=m; end; f:=t; end; end; begin readln(m,n); for i:= 1 to n do readln(w[i],c[i]); writeln(f(m)); end. 说明:当m不大时,编程很简单,但当m较大时,容易超时. 4.2 改进的递归法 改进的的递归法的思想还是以空间换时间,这只要将递归函数计算过程中的各个子函数的值保存起来,开辟一个 一维数组即可 程序如下: program knapsack04; const maxm=2000;maxn=30; type ar=array[0..maxn] of integer; var m,n,j,i,t:integer; c,w:ar; p:array[0..maxm] of integer; function f(x:integer):integer; var i,t,m:integer; begin if p[x]<>-1 then f:=p[x] else begin if x=0 then p[x]:=0 else begin t:=-1; for i:=1 to n do begin if x>=w[i] then m:=f(i-w[i])+c[i]; if m>t then t:=m; end; p[x]:=t; end; f:=p[x]; end; end; begin readln(m,n); for i:= 1 to n do readln(w[i],c[i]); fillchar(p,sizeof(p),-1); writeln(f(m)); end. 3)贪婪算法 改进的背包问题:给定一个超递增序列和一个背包的容量,然后在超递增序列中选(只能选一次)或不选每一个数值,使得选中的数值的和正好等于背包的容量。

代码思路:从最大的元素开始遍历超递增序列中的每个元素,若背包还有大于或等于当前元素值的空间,则放入,然后继续判断下一个元素;若背包剩余空间小于当前元素值,则判断下一个元素 简单模拟如下: #define K 10 #define N 10 #i nclude <stdlib.h> #i nclude <conio.h> void create(long array[],int n,int k) {/*产生超递增序列*/ int i,j; array[0]=1; for(i=1;i<n;i++) { long t=0; for(j=0;j<i;j++) t=t+array[j]; array[i]=t+random(k)+1; } } void output(long array[],int n) {/*输出当前的超递增序列*/ int i; for(i=0;i<n;i++) { if(i%5==0) printf(" "); printf("%14ld",array[i]); } } void beibao(long array[],int cankao[],long value,int count) {/*背包问题求解*/ int i; long r=value; for(i=count-1;i>=0;i--)/*遍历超递增序列中的每个元素*/ { if(r>=array[i])/*如果当前元素还可以放入背包,即背包剩余空间还大于当前元素*/ { r=r-array[i]; cankao[i]=1; } else/*背包剩余空间小于当前元素值*/ cankao[i]=0; } } void main() { long array[N]; int cankao[N]={0}; int i; long value,value1=0; clrscr(); create(array,N,K); output(array,N); printf(" Input the value of beibao: "); scanf("%ld",&value); beibao(array,cankao,value,N); for(i=0;i<N;i++)/*所有已经选中的元素之和*/ if(cankao[i]==1) value1+=array[i]; if(value==value1) { printf(" We have got a solution,that is: "); for(i=0;i<N;i++) if(cankao[i]==1) { if(i%5==0) printf(" "); printf("%13ld",array[i]); } } else printf(" Sorry.We have not got a solution. "); } 贪婪算法的另一种写法,beibao函数是以前的代码,用来比较两种算法: #define K 10 #define N 10 #i nclude <stdlib.h> #i nclude <conio.h> void create(long array[],int n,int k) { int i,j; array[0]=1; for(i=1;i<n;i++) { long t=0; for(j=0;j<i;j++) t=t+array[j]; array[i]=t+random(k)+1; } } void output(long array[],int n) { int i; for(i=0;i<n;i++) { if(i%5==0) printf(" "); printf("%14ld",array[i]); } } void beibao(long array[],int cankao[],long value,int count) { int i; long r=value; for(i=count-1;i>=0;i--) { if(r>=array[i]) { r=r-array[i]; cankao[i]=1; } else cankao[i]=0; } } int beibao1(long array[],int cankao[],long value,int n) {/*贪婪算法*/ int i; long value1=0; for(i=n-1;i>=0;i--)/*先放大的物体,再考虑小的物体*/ if((value1+array[i])<=value)/*如果当前物体可以放入*/ { cankao[i]=1;/*1表示放入*/ value1+=array[i];/*背包剩余容量减少*/ } else cankao[i]=0; if(value1==value) return 1; return 0; } void main() { long array[N]; int cankao[N]={0}; int cankao1[N]={0}; int i; long value,value1=0; clrscr(); create(array,N,K); output(array,N); printf(" Input the value of beibao: "); scanf("%ld",&value); beibao(array,cankao,value,N); for(i=0;i<N;i++) if(cankao[i]==1) value1+=array[i]; if(value==value1) { printf(" We have got a solution,that is: "); for(i=0;i<N;i++) if(cankao[i]==1) { if(i%5==0) printf(" "); printf("%13ld",array[i]); } } else printf(" Sorry.We have not got a solution. "); printf(" Second method: "); if(beibao1(array,cankao1,value,N)==1) { for(i=0;i<N;i++) if(cankao1[i]==1) { if(i%5==0) printf(" "); printf("%13ld",array[i]); } } else printf(" Sorry.We have not got a solution. "); } 4)动态规划算法 解决0/1背包问题的方法有多种,最常用的有贪婪法和动态规划法。

其中贪婪法无法得到问题的最优解,而动态规划法都可以得到最优解,下面是用动态规划法来解决0/1背包问题。

动态规划算法与分治法类似,其基本思想是将待求解问题分解成若干个子问题,然后从这些子问题的解得到原问题的解。

与分治法不同的是,适合于用动态规划法求解的问题,经分解得到的子问题往往不是互相独立的,若用分治法解这类问题,则分解得到的子问题数目太多,以至于最后解决原问题需要耗费过多的时间。

动态规划法又和贪婪算法有些一样,在动态规划中,可将一个问题的解决方案视为一系列决策的结果。

不同的是,在贪婪算法中,每采用一次贪婪准则便做出一个不可撤回的决策,而在动态规划中,还要考察每个最优决策序列中是否包含一个最优子序列。

0/1背包问题 在0 / 1背包问题中,需对容量为c 的背包进行装载。

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

对于可行的背包装载,背包中物品的总重量不能超过背包的容量,最佳装载是指所装入的物品价值最高,即p1*x1+p2*x1+...+pi*xi(其1<=i<=n,x取0或1,取1表示选取物品i) 取得最大值。

在该问题中需要决定x1 .. xn的值。

假设按i = 1,2,...,n 的次序来确定xi 的值。

如果置x1 = 0,则问题转变为相对于其余物品(即物品2,3,.,n),背包容量仍为c 的背包问题。

若置x1 = 1,问题就变为关于最大背包容量为c-w1 的问题。

现设r?{c,c-w1 } 为剩余的背包容量。

在第一次决策之后,剩下的问题便是考虑背包容量为r 时的决策。

不管x1 是0或是1,[x2 ,.,xn ] 必须是第一次决策之后的一个最优方案,如果不是,则会有一个更好的方案[y2,.,yn ],因而[x1,y2,.,yn ]是一个更好的方案。

假设n=3, w=[100,14,10], p=[20,18,15], c= 116。

若设x1 = 1,则在本次决策之后,可用的背包容量为r= 116-100=16 。

[x2,x3 ]=[0,1] 符合容量限制的条件,所得值为1 5,但因为[x2,x3 ]= [1,0] 同样符合容量条件且所得值为1 8,因此[x2,x3 ] = [ 0,1] 并非最优策略。

即x= [ 1,0,1] 可改进为x= [ 1,1,0 ]。

若设x1 = 0,则对于剩下的两种物品而言,容量限制条件为116。

总之,如果子问题的结果[x2,x3 ]不是剩余情况下的一个最优解,则[x1,x2,x3 ]也不会是总体的最优解。

在此问题中,最优决策序列由最优决策子序列组成。

假设f (i,y) 表示剩余容量为y,剩余物品为i,i + 1,...,n 时的最优解的值,即:利用最优序列由最优子序列构成的结论,可得到f 的递归式为: 当j>=wi时: f(i,j)=max{f(i+1,j),f(i+1,j-wi)+vi} ①式 当0<=j<wi时:f(i,j)=f(i+1,j) ②式 fn( 1 ,c) 是初始时背包问题的最优解。

以本题为例:若0≤y<1 0,则f ( 3 ,y) = 0;若y≥1 0,f ( 3 ,y) = 1 5。

利用②式,可得f (2, y) = 0 ( 0≤y<10 );f(2,y)= 1 5(1 0≤y<1 4);f(2,y)= 1 8(1 4≤y<2 4)和f(2,y)= 3 3(y≥2 4)。

因此最优解f ( 1 , 11 6 ) = m a x {f(2,11 6),f(2,11 6 - w1)+ p1} = m a x {f(2,11 6),f(2,1 6)+ 2 0 } = m a x { 3 3,3 8 } = 3 8。

现在计算xi 值,步骤如下:若f ( 1 ,c) =f ( 2 ,c),则x1 = 0,否则x1 = 1。

接下来需从剩余容量c-w1中寻求最优解,用f (2, c-w1) 表示最优解。

依此类推,可得到所有的xi (i= 1.n) 值。

在该例中,可得出f ( 2 , 116 ) = 3 3≠f ( 1 , 11 6 ),所以x1 = 1。

接着利用返回值3 8 -p1=18 计算x2 及x3,此时r = 11 6 -w1 = 1 6,又由f ( 2 , 1 6 ) = 1 8,得f ( 3 , 1 6 ) = 1 4≠f ( 2 , 1 6 ),因此x2 = 1,此时r= 1 6 -w2 = 2,所以f (3,2) =0,即得x3 = 0。

0/1背包 回溯算法

#include using namespace std; struct bag{ double w; double p; double p_w; int order; }; //说明物品特性 void sort(struct bag *a,int low,int high); int main() { int n,i; double *x; //解向量,由于书数组,拿指针表示 double m,cost=0; struct bag *b; //结构数组,用于表示所有物品 //定义文件流并与具体的磁盘文件相关联 ifstream fin; fin.open("背包问题_in.txt"); ofstream fout; fout.open("背包问题_out.txt"); //输入物品数目 n 背包容量 M fin>>n>>m; //动态分配存储空间 b=new struct bag[n]; x=new double[n]; for(i=0;i>b[i].w>>b[i].p; //输入物品重量和运价 b[i].p_w=b[i].p/b[i].w; //求出运价重量比 b[i].order=i; //贴标签 } sort(b,0,n-1); //按运价重量比从大到小进行排序 for(i=0;i=t) ++low; a[high]=a[low]; } a[low]=temp; return low; } void sort(struct bag *a,int low,int high) { int loc; if(low用贪心算法解决背包问题用贪心算法解决背包问题,首先要明白,结果不一定是全局最优的。

对于贪心法而言,首先步骤是找到最优度量标准,我这里的算法采用的最优度量标准是: 收益p/重量w 的值最大者优先放入背包中,所以有算法如下:void GreedyKnapsack(float * x){ //前置条件:w[i]已按p[i]/w[i]的非增次序排列 float u=m; //u为背包剩余载重量,初始时为m for(int i=0;iu) break; x[i]=1.0; u=u-w[i]; } if(i背包问题伪多项式算法是什么意思问题描述: 给定n种物品和一背包,物品i的重量是wi,其价值为vi,背包的容量为C。

问应如何选择装入背包的物品(物品不能分割),使得装入背包中物品的总价值最大?抽象描述如下: x[n]:表示物品的选择,x[i]=1表示选择放进物品i到背包中。

问题分析: 1.抽象之后背包问题转换为找到一个最优的数组,x1,x2,..,xn的0-1序列。

2.假设最优解的序列为x1,x2,..,xn,能使背包容量C的总价值最大. 如果,x1=1,则x2,,xn是C-w1容量的背包的总价值依然是最大的序列; 如果,x1=0,则x2,.,xn是C容量的背包的总价值依然是最大的序列。

这就是我们所说的最优子结构性质。

3.进一步分析:我们用m(i,j)表示为已经判断好了1:i-1的序列的背包最大价值,并且此时的背包剩余的容量为j,对物品i进行判断 如果j>wi,就只要做出选择wi和不选择wi情况下,哪种更能使背包的总价值更大:m(i,j)=max{m(i+1,j),m(i+1,j-wi)+vi}(注意这是个递归式) 如果j=wn); m(n,j)=0 (0<=j

百纵科技(19元/月),美国洛杉矶10G防御服务器/洛杉矶C3机房 带金盾高防

百纵科技官网:https://www.baizon.cn/百纵科技:美国云服务器活动重磅来袭,洛杉矶C3机房 带金盾高防,会员后台可自助管理防火墙,添加黑白名单 CC策略开启低中高.CPU全系列E52680v3 DDR4内存 三星固态盘列阵。另有高防清洗!美国洛杉矶 CN2 云服务器CPU内存带宽数据盘防御价格1H1G10M10G10G19元/月 购买地址2H1G10M10G10G29元/月 购买...

华圣云 HuaSaint-阿里云国际站一级分销商,只需一个邮箱即可注册国际账号,可代充值

简介华圣云 HuaSaint是阿里云国际版一级分销商(诚招募二级代理),专业为全球企业客户与个人开发者提供阿里云国际版开户注册、认证、充值等服务,通过HuaSaint开通阿里云国际版只需要一个邮箱,不需要PayPal信用卡,不需要买海外电话卡,绝对的零门槛,零风险官方网站:www.huasaint.com企业名:huaSaint Tech Limited阿里云国际版都有什么优势?阿里云国际版的产品...

Stablehost 美国主机商黑五虚拟主机四折

如今我们网友可能较多的会选择云服务器、VPS主机,对于虚拟主机的话可能很多人不会选择。但是我们有些外贸业务用途的建站项目还是会有选择虚拟主机的。今天看到的Stablehost 商家虚拟主机在黑五期间也有四折优惠,对于这个服务商而言不是特别的喜欢,虽然他们商家和我们熟悉的老鹰主机商有些类似,且在后来老鹰主机改版和方案后,Stablehost 商家也会跟随改版,但是性价比认为不如老鹰主机。这次黑色星期...

背包问题回溯法为你推荐
容灾备份目前有哪些容灾备份技术swift语言Swift 集成了哪些语言的特性支付宝账单查询支付宝怎么查询交易记录硬盘分区格式化如何将电脑里的所有硬盘分区全部格式化?摇一摇周边公众号怎么用微信摇一摇周边功能购物网站设计Jsp+Sql电子商城&网上购物网站设计海淀区公司注册在北京海淀区注册的有限责任公司,要增加自然人股东,需要准备哪些材料?里程碑2里程碑2 如何。?gps简介GPS有哪些功能我的电脑打开很慢电脑开机慢怎么办电脑速度慢怎么办
网站空间价格 怎么注册域名 长春域名注册 台湾服务器租用 免费vps namecheap php主机 56折 512m内存 网盘申请 卡巴斯基官方免费版 91vps nerds 1g空间 ftp免费空间 搜索引擎提交入口 香港新世界中心 四川电信商城 双线asp空间 万网空间管理 更多