01背包问题四种不同算法的实现Word文档下载推荐.docx

上传人:b****3 文档编号:14843007 上传时间:2022-10-25 格式:DOCX 页数:40 大小:173.33KB
下载 相关 举报
01背包问题四种不同算法的实现Word文档下载推荐.docx_第1页
第1页 / 共40页
01背包问题四种不同算法的实现Word文档下载推荐.docx_第2页
第2页 / 共40页
01背包问题四种不同算法的实现Word文档下载推荐.docx_第3页
第3页 / 共40页
01背包问题四种不同算法的实现Word文档下载推荐.docx_第4页
第4页 / 共40页
01背包问题四种不同算法的实现Word文档下载推荐.docx_第5页
第5页 / 共40页
点击查看更多>>
下载资源
资源描述

01背包问题四种不同算法的实现Word文档下载推荐.docx

《01背包问题四种不同算法的实现Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《01背包问题四种不同算法的实现Word文档下载推荐.docx(40页珍藏版)》请在冰豆网上搜索。

01背包问题四种不同算法的实现Word文档下载推荐.docx

j++)

if(c[j]<

c[j+1])

{t1=a[j];

a[j]=a[j+1];

a[j+1]=t1;

t2=b[j];

b[j]=b[j+1];

b[j+1]=t2;

t3=c[j];

c[j]=c[j+1];

c[j+1]=t3;

}

voidknapsack(intn,floatlimitw,floatv[max],floatw[max],intx[max])

{floatc1;

//c1为背包剩余可装载重量

inti;

sort(n,v,w);

//物品按价值密度排序

c1=limitw;

for(i=0;

i<

i++)

if(w[i]>

c1)break;

x[i]=1;

//x[i]为1时,物品i在解中

c1=c1-w[i];

voidmain()

{intn,i,x[max];

floatv[max],w[max],totalv=0,totalw=0,limitw;

cout<

<

"

请输入n和limitw:

;

cin>

>

n>

limitw;

for(i=1;

=n;

x[i]=0;

//物品选择情况表初始化为0

请依次输入物品的价值:

endl;

v[i];

请依次输入物品的重量:

w[i];

knapsack(n,limitw,v,w,x);

theselectionis:

x[i];

if(x[i]==1){

totalw=totalw+w[i];

totalv=totalv+v[i];

背包的总重量为:

totalw<

//背包所装载总重量

背包的总价值为:

totalv<

//背包的总价值

4、贪心算法运行结果如下图所示:

方案二:

动态规划算法

1、动态规划的基本原理与分析

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

但是经分解得到的子问题往往不是互相独立的。

不同子问题的数目常常只有多项式量级。

如果能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,就可以避免大量重复计算,从而得到多项式时间算法。

它把已知问题分为很多子问题,按顺序求解子问题,在每一种情况下,列出各种情况的局部解,按条件从中选取那些最有可能产生最佳的结果舍弃其余。

前一子问题为后面子问题提供信息,而减少计算量,最后一个子问题的解即为问题解。

采用此方法求解0-1背包问题的主要步骤如下:

①分析最优解的结构:

最有子结构性质;

②建立递归方程;

③计算最优值;

④构造最优解[4]。

2、0-1背包问题的实现

①最优子结构性质

0-1背包问题具有最优子结构性质。

设(y1,y2…yn)是所给0-1背包问题的一个最优解,则(y2,y3…yn)是下面相应子问题的一个最优解:

因若不然,设(z2,z3…zn)是上述问题的一个最优解,而(y2,y3…yn)不是它的最优解,由此可见,且c。

因此

c

这说明(y1,z2…zn)是所给0-1背包问题的一个更优解,从而(y1,y2…yn)不是所给0-1背包问题的最优解。

此为矛盾[1]。

②递归关系

设所给0-1背包问题的子问题

的最优值为m(i,j),即m(i,j)是背包容量为j,可选择物品为i,i+1,……,n时0-1背包问题的最优值。

由0-1背包问题的最优子结构性质,可以建立计算m(i,j)的递归式如下:

iostream>

iomanip>

usingnamespacestd;

constintMAX=1000;

intw[MAX],v[MAX],best[MAX];

intV[MAX][MAX];

//最大价值矩阵

intW,n;

//W为背包的最大载重量,n为物品的数量

//求最大值函数

intmax(intx,inty)

returnx>

=y?

x:

y;

//求最小值函数

intmin(intx,inty)

returnx>

=y?

y:

x;

voidKnaspack()

intMax=min(w[n]-1,W);

for(intj=1;

j<

=Max;

j++)

V[n][j]=0;

for(j=w[n];

=W;

V[n][j]=v[n];

for(inti=n-1;

i>

1;

i--)

{

Max=min(w[i]-1,W);

for(j=1;

V[i][j]=V[i+1][j];

for(j=w[i];

=W;

V[i][j]=max(V[i+1][j],V[i+1][j-w[i]]+v[i]);

}

V[1][W]=V[2][W];

//先假设第一个物品不放入

if(W>

w[1])

V[1][W]=max(V[1][W],V[2][W-w[1]]+v[1]);

//生成向量数组,决定某一个物品是否应该放入背包

voidTraceback()

for(inti=1;

i<

n;

i++)//比较矩阵两邻两行(除最后一行),背包容量为W的最优值.

if(V[i][W]==V[i+1][W])//如果当前行的最优值与下一行的最优值相等,则表明该物品不能放入。

best[i]=0;

else//否则可以放入

{

best[i]=1;

W-=w[i];

}

}

best[n]=(V[n][W])?

1:

0;

{

cout<

输入商品数量n和背包容量W:

cin>

n>

W;

输入每件商品的重量w:

cin>

memset(V,0,sizeof(V));

输入每件商品的价值v:

for(i=1;

Knaspack();

//构造矩阵

Traceback();

//求出解的向量数组

inttotalW=0;

inttotalV=0;

//显示可以放入的物品

所选择的商品如下:

序号i:

重量w:

价格v:

for(i=1;

=n;

i++)

if(best[i]==1)

totalW+=w[i];

totalV+=v[i];

cout<

setiosflags(ios:

:

left)<

setw(5)<

"

w[i]<

v[i]<

放入的物品重量总和是:

totalW<

价值最优解是:

V[1][W]<

totalV<

4、计算复杂性分析

利用动态规划求解0-1背包问题的复杂度为0(min{nc,2n}。

动态规划主要是求解最优决策序列,当最优决策序列中包含最优决策子序列时,可建立动态规划递归方程,它可以帮助高效地解决问题[8]。

5、动态规划运行结果如下图所示:

方案三:

回溯法

1、回溯法的基本原理与分析

回溯是一种系统地搜索问题解答的方法。

为了实现回溯,首先需要为问题定义一个解空间,这个解空间必须至少包含问题的一个解(可能是最优的)。

回溯法需要为问题定义一个解空间,这个解空间必须至少包含问题的一个解(可能是最优的)。

使用递归回溯法解决背包问题的优点在于它算法思想简单,而且它能完全遍历搜索空间,肯定能找到问题的最优解奉但是由于此问题解的总组合数有个,因此随着物件数n的增大,其解的空间将以n级增长,当n大到一定程度上,用此算法解决背包问题将是不现实的。

下一步是组织解空间以便它能被容易地搜索。

典型的组织方法是图或树。

一旦定义了解空间的组织方法,这个空间即可按照深度优先的方法从开始结点进行搜索,利用限界函数避免移动到不可能产生解的子空间。

回溯法是一种系统地搜索问题解答的方法。

一旦定义了解空间的组织方要选择一个对象的子集,将它们装人背包,以便获得的收益最大,则解空间应组织成子集树的形状。

首先形成一个递归算法,去找到可获得的最大收益。

然后,对该算法加以改进,形成代码。

改进后的代码可找到获得最大收益时包含在背包中的对象的集合。

左子树表示一个可行的结点,无论何时都要移动到它,当右子树可能含有比当前最优解还优的解时,移动到它。

一种决定是否要移动到右子树的简单方法是r为还未遍历的对象的收益之和,将r加到cp(当前节点所获收益)之上,若(r+cp)bestp(目前最优解的收益),则不需搜索右子树。

一种更有效的方法是按收益密度vi/wi对剩余对象排序,将对象按密度递减的顺序去填充背包的剩余容量,当遇到第一个不能全部放人背包的对象时,就使用它的一部分。

classKnap

friendintKnapsack(intp[],intw[],intc,intn);

public:

voidprint()

for(intm=1;

m<

m++)

bestx[m]<

};

private:

intBound(inti);

voidBacktrack(inti);

intc;

//背包容量

int

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 商务科技

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1