您的位置:首页 > 编程语言 > MATLAB

背包问题,动态规划求解,matlab代码,c++代码

2016-09-08 16:42 751 查看
最近写论文接触到背包问题,查阅网上一些资料,对于简单的背包问题,动态规划算法可以求解,最近花时间整理整理。

背包问题描述:

有编号分别为a,b,c,d,e 的五件物品,它们的重量分别是 2,2,6,5,4,它们的价值分别是 6,3,5,4,6,现在给你个承重为 10 的背包,如何让背包里装入的物品具有最大的价值总和? (假设每类物品可以装多个)

根据求解动态规划问题的步骤,一步一步来。用 ci 表示各物品的重量,vi 表示各物品的价值。

阶段:

\begin{equation}i=1,2,\dots,5\end{equation}

第 i  阶段表示检查第 i 个物品。

状态变量:

\begin{equation}S_{i}\qquad i=1,2,\dots,5\end{equation}

表示检查第 i 个物品时包中的剩余承重量。一个问题能够用动态规划算法求解,必须保证状态空间是有限的。

决策变量:

\begin{equation}x_{i}\qquad i=1,2,\dots,5\end{equation}

表示第 i 个物品装入几个。

状态转移方程:

\begin{equation}S_{i+1}=S_{i}-c_{i}x_{i}\end{equation}

最优收益函数:

\begin{equation}\mathop{f}(S_{i})\end{equation}

表示检查第 i 个物品时,当包中剩余承重为 Si,包中装入物品 i, i+1, ... 5 能达到的最大价值。

最优收益函数转移方程:

\begin{equation}\mathop{f}\limits_{c_{i}x_{i}\leq S_{i}}(S_{i})= \begin{cases} v_{i}x_{i}+f(S_{i+1})\quad &i=1,2,\dots 4\\ v_{i}x_{i}\quad &i=5 \end{cases}\end{equation}

得到最优转移方程时,就可以求解了。从上式可以看出要用逆推法求解。当然也可以用顺推法求解,不过需要改变最优收益函数的定义。

动态规划求解时,都可以用矩阵来递推。

用了一位的前辈的图: http://blog.csdn.net/mu399/article/details/7722810。 我稍微改了下,不是0-1 背包,每类物品可以装多个。

这个图画的真不错!只是少了一列,s=0 的一列。

nameweightvalue12345678910
a2606612121818242430
b230336699121215
c650006666121212
d540006666121212
e460006666121212
最优解是装入 5 个物品 a !

matlab 代码:

function Knapsack
c=[2 2 6 5 4];v=[6 3 5 4 6];
f=zeros(5,11);x=zeros(5,11);xx=zeros(5,1);
for i=5:-1:1
for S=0:10
if i==5
f(i,S+1)=v(i)*floor(S/c(i));
x(i,S+1)=floor(S/c(i));
else
xMax=floor(S/c(i));
ff=zeros(xMax+1,1);
for k=0:xMax
ff(k+1)=v(i)*k+f(i+1,S-c(i)*k+1);
end
[f(i,S+1),index]=max(ff);
x(i,S+1)=index-1;
end
end
end
[optValue,index]=max(f(1,:));
xx(1)=x(1,index);
tempS=index;
fprintf('optimal solution:%d\n',optValue);
for i=2:5
xx(i)=x(i,tempS-c(i-1)*xx(i-1));
tempS=tempS-c(i-1)*xx(i-1);
end
for i=1:5
fprintf('put %d item%d in the bag\n',xx(i),i);
end

end


输出结果:

optimal solution:30

put 5 item1 in the bag

put 0 item2 in the bag

put 0 item3 in the bag

put 0 item4 in the bag

put 0 item5 in the bag

c ++ 代码:

用到了动态数组,以及能够返回一个数组的函数。

#include"stdio.h"
#include"stdlib.h"

int * Max(int *arr, int n)
{
int *a=(int *)malloc(2*sizeof(int));
a[0]=0;a[1]=0;
for (int i=0;i<n;i++)
{
if (arr[i]>a[0])
{
a[0]=arr[i];a[1]=i;
}
}
return a;
}

void main()
{
static const int c[5]={2,2,6,5,4};
static const int v[5]={6,3,5,4,6};

int f[5][11];
int x[5][11];
int itemNum[5];

for (int i=5;i>0;i--)
for (int S=0;S<11;S++)
{
if (i==5)
{
f[i-1][S]=v[i-1]*(S/c[i-1]);
x[i-1][S]=S/c[i-1];
}
else
{
int xMax=S/c[i-1];
int * ff= (int *)malloc(sizeof(int)*(xMax+1));
for(int k=0;k<=xMax;++k)
ff[k]=v[i-1]*k+f[i][S-c[i-1]*k];
int *a=Max(ff,xMax+1);
f[i-1][S]=a[0];x[i-1][S]=a[1];
free(a);
free(ff);
}
}

int *temp=f[0];
int *maxValue=Max(temp,11);
int tempS=maxValue[1];
itemNum[0]=x[0][tempS];
for (int i=1;i<5;++i)
{
itemNum[i]=x[i][tempS-c[i-1]*itemNum[i-1]];
tempS-=c[i-1]*itemNum[i-1];
}
printf("the optimal solution is: %d\n",maxValue[0]);
for(int i=0;i<5;i++)
printf("put %d item%d in the bag\n",itemNum[i],i+1);
free(maxValue);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: