数学建模背包问题.docx
《数学建模背包问题.docx》由会员分享,可在线阅读,更多相关《数学建模背包问题.docx(9页珍藏版)》请在冰豆网上搜索。
数学建模背包问题
背包问题
背包问题(Knapsackproblem)是一种组合优化的NP完全问题。
问题可以描述为:
给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。
问题的名称来源于如何选择最合适的物品放置于给定背包中。
相似问题经常出现在商业、组合数学,计算复杂性理论、密码学和应用数学等领域中。
也可以将背包问题描述为决定性问题,即在总重量不超过W的前提下,总价值是否能达到V?
它是在1978年由Merkel和Hellman提出的
一、定义:
背包问题属于组合优化问题,一般的最优化问题由目标函数和约束条件两部部分组成:
我们有n种物品,物品i的重量为w
i,价格为p
i。
我们假定所有物品的重量和价格都是非负的。
背包所能承受的最大重量为W。
如果限定每种物品只能选择0个或1个,则问题称为0-1背包问题。
可以用公式表示为:
maxå
p
ix
i
i=1
n
S.T.å
w
ix
i£W,x
iÎ{
0,}
1
i=1
n
如果限定物品i最多只能选择b
i个,则问题称为有界背包问题。
可以用公式表示为:
maxå
p
ix
i
i=1
n
S.T.
å
wx
i=1
n
iix
iÎ{
0,1,
£W,×××b
i,}
如果不限定每种物品的数量,则问题称为无界背包问题。
各类复杂的背包问题总可以变换为简单的0-1背包问题进行求解。
二、基本模型的建立方法
1、0-1背包问题的数学模型(最基础的背包问题)
分类:
0-1背包问题简单分为一维背包和二维背包问题。
特点:
每种物品仅有一件,可以选择放或不放。
1.1一维背包问题
问题:
一个旅行者准备进行徒步旅行,为此他必须决定携带若干物品。
设有n件物品可供他选择,编号为1,2,...,n第i件物品重量为w
i千克,价值为p
i元,他能携带的最大重量为w千克。
他应该装入哪几件物品价值最大。
解:
引入变量x
i,且设
ì1,表示将第i种物品装入包中
x
i=
í(i=1,2,,n)
0,表示不将第i种物品装入包
î
于是此问题的数学模型为:
maxf=å
p
ix
i
i=1
n
ìw
1x
1+w
2x
2+...+w
nx
n£W
S.T.
í
x=0或1,i=1,2,...,n.
î
i
1.2二维背包问题
一维背包问题只考虑了背包重量的限制,如果再增加背包体积的限制为V,并设第i件物品的体积v
i,问如何携带可使总价值最大。
这就是二维背包问题。
它的数学模型为:
maxf=å
p
ix
i
i=1
n
ìw
1x
1+w
2x
2+...+w
nx
n£W
ï
S.T.
ív
1x
1+v
2x
2+...+v
nx
n£V
ï
x=0或1,i=1,2,...,n.
î
i
2、有界背包的数学模型
特点:
能够选择的物品数则可以在某个范围内取值。
物品j最多可以选择m
j个,那么有界背包问题可以描述为:
maxf=å
p
ix
i
i=1
n
...,
S.T.å
w
ix
i£Cx
iÎ{
0,1,m
j}
j=
i=1
n
1,n2,...,.3、无界背包问题的数学模型
特点:
无界背包问题实际上就是有界背包问题的扩展,每个物品可以任意的取。
但是因为背包的承重能力有限,每个物品的数目不可能取到无穷大,因此,实际上它仍是一个有界背包问题。
适用范围:
背包问题(KnapsackProblem)是组合优化领域内经典的NP完备问题,是一个在运筹学领域常见的优化难题。
背包问题的研究起源于旅行者携带用品的背景,要求在旅行袋容积有一定限制的情况下,如何分配资源使得收益最大。
很多问题都可以建模为背包问题,如在管理中的资源分配、资金预算、投资决策、货物装载、项目选择,工厂里的下料问题等上都有着广泛的应用。
。
0-1背包源程序:
#include
#definen5
#definem10
voidknapbag(int*w,int*vl)
{
intc[n+1][m+1];//从1…i…item物品中,背包剩余空间为0<=j<=max_wgt的最大价值for(inti=0;i<=n;i++)//初始化
{
for(intj=0;j<=m;j++)
{
c[i][j]=0;
}
}
//c(i,j)=max{c(i-1,j),c(i-1,j-w[i])+vl(i)}
for(i=1;i<=n;i++)
{
for(intj=1;j<=m;j++)
{
if(w[i]<=j)
{
if(vl[i]+c[i-1][j-w[i]]>c[i-1][j])
{
c[i][j]=vl[i]+c[i-1][j-w[i]];//选择第i物品
}
else
c[i][j]=c[i-1][j];//不选择第i个物品
}
else
c[i][j]=c[i-1][j];//剩余容量不够
}//endfor
}//endfor
cout<<"最优解:
";
cout<////算出是由哪几个物品组成
inttemp_wei=m;
intx[n+1]={0,0,0,0};
for(i=n;i>0;i--)
{
if(c[i][temp_wei]==c[i-1][temp_wei])//最后一个肯定是最大价值的
{
x[i]=0;
}
else
{
x[i]=1;
temp_wei-=w[i];
}
}
cout<<"应装入的物品有:
";
for(i=0;i<=n;i++)
{
if(x[i])
{
cout<<"第"<
}
}
cout<}
intmain()
{
intw[6]={0,2,2,6,5,4};//物品质量
intvl[6]={0,6,3,5,4,6};//物品价值
knapbag(w,vl);
return0;
}