分组背包问题Matlab实现——之基本背包问题

2016年7月27日星期三

T.s.road总结笔记:分组背包问题Matlab实现——之基本背包问题

项目源码:https://github.com/Tsroad/KnapsackProblemSeries


作者说明:

When running thisprogramme, the author’s PCsetting is:

Microsoft Windows 7 (SP1) + Matlab R2010b +CPUi5-4590 + RAM 4.0GB.

 (LabSX309; Check by Keung Charteris or T.s.road CZQ & F.Hong)

题目

有N件物品和一个容量为C的背包。第i件物品的价值是V[i],重量是W[i]。求解将哪些物品装入背包,使得重量总和不超过背包容量,且价值总和最大。

 

基本思路

这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。其状态转移方程便是:

M(i,v)=max{第i件物品不放入背包, 第i件物品放入背包}

M(i,v)=max{M( i-1 , C) , M( i-1 , C-W(i) ) + V(i)}

用子问题定义状态:即M(i,v)表示前i件物品恰放入一个容量为C的背包可以获得的最大价值。

M(i,v)=max{(不放入物品i)将前i-1件物品放入容量为C的背包中的最大价值,

(放入物品i)将前i-1件物品放入容量为C- W(i)的背包中的最大价值+ V(i)}

 

这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的。所以有必要将它详细解释一下:“将前i件物品放入容量为C的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为C的背包中”;如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的容量为C-W(i)的背包中”,此时能获得的最大价值就是M( i-1 , C-W(i) )再加上通过放入第i件物品获得的价值V(i)。

%   问题分析
% 1. 判断第一个物品放或不放;
% 2. 判断下一个物品是放还是不放;M[i,c]=M[i-1,c] or M[i,c]= M[i-1,c-w(i)]+v(i);
% 3. 重复2;
% 4. 找出这些物品。


clc;  %清除所有
clear all;%清除变量
close all;%关闭图片

Capacity=10;% 背包的容量
Weight= [0,2,2,6,5,4];% 物品的重量,其中0号位置不使用 。
Value= [0,6,3,5,4,6];% 物品对应的价钱,0号位置置为空。
NumberOfObject =length(Weight);% n为物品的个数
TransferMatrix=[];%定义状态转移矩阵
ObjectState=[];%背包里物品的状态

%1.判断第一个物品放或不放;
for FlagTemp=1:11
        if Weight(NumberOfObject)<FlagTemp
                TransferMatrix(NumberOfObject,FlagTemp)=Value(NumberOfObject) ;
        else
                TransferMatrix(NumberOfObject,FlagTemp)=0;
        end
end

%2.判断下一个物品是放还是不放;不放时:F[i,v]=F[i-1,v];放时:F[i,v]=max{F[i-1,v],F[i-1,v-C_i]+w_i};
%3.重复2.
for FlagTempExternal=NumberOfObject-1:-1:1
        for FlagTemp=1:11
                if FlagTemp<=Weight(FlagTempExternal)
                        TransferMatrix(FlagTempExternal,FlagTemp)=TransferMatrix(FlagTempExternal+1,FlagTemp);
                else
                        if TransferMatrix(FlagTempExternal+1,FlagTemp)>TransferMatrix(FlagTempExternal+1,FlagTemp-Weight(FlagTempExternal))+Value(FlagTempExternal)
                                TransferMatrix(FlagTempExternal,FlagTemp)=TransferMatrix(FlagTempExternal+1,FlagTemp);
                        else
                                TransferMatrix(FlagTempExternal,FlagTemp)=TransferMatrix(FlagTempExternal+1,FlagTemp-Weight(FlagTempExternal))+Value(FlagTempExternal);
                        end
                end
        end
end
TransferMatrix

%4.找出这些物品。

FlagTempExternal=Capacity;
for FlagTemp=1:NumberOfObject-1
        if TransferMatrix(FlagTemp,FlagTempExternal)==TransferMatrix(FlagTemp+1,FlagTempExternal)
                ObjectState(FlagTemp)=0;
        else
                ObjectState(FlagTemp)=1;
                FlagTempExternal=FlagTempExternal-Weight(FlagTemp);
        end
end
if TransferMatrix(NumberOfObject,FlagTempExternal)==0
        ObjectState(NumberOfObject)=0;
else
        ObjectState(NumberOfObject)=1;
        
end

ObjectState

运行结果:


 

  • 20
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据引用\[1\]和引用\[2\]的描述,我们可以使用动态规划来解决分组背包问题。以下是一个使用MATLAB编写的分组背包问题代码示例: ```matlab function \[maxValue, selectedItems\] = groupKnapsack(values, volumes, weights, capacity) n = length(values); % 物品总数 m = length(values{1}); % 每组物品数量 % 初始化动态规划表 dp = zeros(n+1, capacity+1); % 递推计算最大价值 for i = 1:n for j = 1:capacity for k = 1:m if volumes{i}(k) <= j dp(i+1, j) = max(dp(i+1, j), dp(i, j-volumes{i}(k)) + values{i}(k)); end end end end % 回溯获取选中的物品 selectedItems = cell(1, n); j = capacity; for i = n:-1:1 for k = 1:m if volumes{i}(k) <= j && dp(i+1, j) == dp(i, j-volumes{i}(k)) + values{i}(k) selectedItems{i} = \[selectedItems{i}, k\]; j = j - volumes{i}(k); break; end end end maxValue = dp(n+1, capacity); end ``` 这段代码实现了一个名为`groupKnapsack`的函数,它接受四个参数:`values`表示每个物品的价值,`volumes`表示每个物品的体积,`weights`表示每个物品的重量,`capacity`表示背包的容量。函数返回最大价值`maxValue`和选中的物品`selectedItems`。 请注意,这段代码假设每个组中的物品数量相同,并且每个物品的体积和重量都是一个数组。你可以根据自己的实际情况进行修改。 希望这个代码示例能够帮助到你解决MATLAB中的分组背包问题。 #### 引用[.reference_title] - *1* [分组背包问题Matlab实现——之基本背包问题](https://blog.csdn.net/tsroad/article/details/52048562)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [基于粒子群算法的分组背包MATLAB实现](https://blog.csdn.net/weixin_42506994/article/details/116062734)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值