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

来源:互联网 发布:dota 知乎 编辑:程序博客网 时间:2024/05/20 13:19

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


背包问题描述:

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


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


阶段:

,

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


状态变量:


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


决策变量:


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


状态转移方程:


最优收益函数:


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


最优收益函数转移方程:



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


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

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

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

nameweightvalue12345678910a2606612121818242430b230336699121215c650006666121212d540006666121212e460006666121212
最优解是装入 5 个物品 a !


matlab 代码:

function Knapsackc=[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    endend[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);endfor i=1:5    fprintf('put %d item%d in the bag\n',xx(i),i);endend



输出结果:

optimal solution:15
put 0 item1 in the bag
put 1 item2 in the bag
put 0 item3 in the bag
put 0 item4 in the bag

put 2 item5 in the bag


c 语言代码,我编写成了 cpp格式,因为严格的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);}



0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 魅族手机打电话黑屏怎么办 三星手机拨打电话时黑屏怎么办 华为畅享5打电话黑屏怎么办 小米note通话声音小怎么办 金立m5黑屏开不了机怎么办 金立手机光感器坏了怎么办 红掌根部烂了怎么办 魅族相册闪退怎么办 魅族手机闪退怎么办 苹果6手机主页面打不开怎么办 手机中病毒闪退怎么办 酷派手机开机黑屏怎么办啊 酷派手机黑屏打不开怎么办 酷派手机不开机怎么办 乐视手机开不了机怎么办 vivo手机拨号键盘不见了怎么办 华为手机拨号键盘不见了怎么办 金立手机拨号键盘不见了怎么办 酷派手机home键失灵怎么办 r11屏碎一半黑屏怎么办 金立手机黑屏打不开怎么办 小米8se自动跳出广告怎么办 小米手机总跳出广告怎么办 小米手机总是出现广告怎么办 红米1s开机黑屏怎么办 红米手机打电话黑屏怎么办 小米4c打游戏卡怎么办 电脑总出现拨号连接怎么办 win10电脑没有拨号连接怎么办 红米手机黑屏了怎么办 小米4s黑屏了怎么办 鼠标的左键失灵怎么办 小米5左键失灵怎么办 小米4左键失灵怎么办 小米5s左键失灵怎么办 单击鼠标左键就会自动删除?怎么办 华为五s开不开机怎么办 荣耀8关不了机怎么办 三星s7左键失灵怎么办 华为mate7死机黑屏了怎么办 小米手机max黑屏打不开怎么办