我如何解决 0-1 背包算法的这些变体?
Posted
技术标签:
【中文标题】我如何解决 0-1 背包算法的这些变体?【英文标题】:How do i solve these variations of the 0-1 knapsack algorithm? 【发布时间】:2016-07-21 22:04:01 【问题描述】:背包可以承载最大重量,比如 max_wt ;有 n 个具有给定权重wt[]
和值val[]
的项目。我有两个问题(彼此分开):
我的尝试
对于第一个问题,我提到了this*** 帖子,但我能理解的唯一答案是两个约束合并的地方,但我猜它的运行时间复杂度会很大......我在想的是制作一个dp[i][j][k]
,其中 i 是选择的项目数,j 是当时选择的 max-wt,k 是当时选择的 max-vol,然后我的代码核心看起来像for(i=0 ; i < n ; i++) \\ n is no. of items
for(j=0 ; j < n ; j++)
for(k=0 ; k < n ; k++)
dp[i][j][k] = max( dp[i-1][j][k] , val[i] + dp[i-1][j-wt[j]][k-vol[k]]) ;
,这似乎没问题,但给了我错误的答案......我猜不出为什么:(
我无法开始思考第二个问题,我的朋友通过采取三个状态 dp[i][j][k] 做到了,其中 i 和 j 与第一个问题相同(通常的) 虽然 'k' 跟踪所选项目的总数,但这个想法并没有出现在我的脑海中。另外,状态将存储什么,它通常存储可能的最大值,直到经典背包问题中的给定状态,这里我猜一个状态将存储可被 8 整除的总组合直到该状态,但我无法将其转换为代码。
p.s 请尝试为第二个问题提供自下而上的解决方案,我对动态编程非常陌生。 ;)
【问题讨论】:
最大的路数是多少... - 你是指路数吗?如果不是,最大值指的是什么? “这样它们的总和可以被一个数整除” - 什么的总和?重量/体积还是其他? 对不起,我的问题还不清楚,这里又是一个完整的问题:给定 var[ ] , wt[ ] of n 个项目,我们如何为我们的背包准确选择 z( @DanielRodriguez sum of value ,只是第二个问题没有体积限制的值 @Gassa 我措辞错误..我的意思只是方式的数量...谢谢你挑出来 【参考方案1】:二维背包问题
设n
为项目数
让val[i]
为i
-th 项的值
设w[i]
为i
-th 项的权重
设v[i]
为i
-th item的音量
让T[i,j,k]
成为第一个i
项目中的最佳价值,并且具有精确 重量j
和体积k
。 T
可以用其他方式定义,但这个定义给出了一个简短的公式。
寻找最佳价值
T[0,j,k] = 0
T[i,j,k] = T[i-1,j,k]
,当j<w[i]
或k<v[i]
,否则:
T[i,j,k] = max( T[i-1,j,k] , T[i-1,j-w[i],k-i] + val[i] )
对于所有 j 和 k,最佳可能值是 max T[n,j,k]
实施说明
首先为所有 j
和 k
初始化基本情况
从 1 到 n 循环 i
并与基于 1 的数组索引保持一致
循环 j
从 1 到最大可能权重,这是所有权重的总和,例如w[1]+w[2]+...w[n]
循环 k
从 1 到最大可能音量
用精确的项目数计算获得精确值的方法数
设S[i,j,k,l]
是第一个i
项目可以按照重量j
、价值k
和l
项目排列的方式数。
S[0,j,k,l] = 0
,S[0,0,0,0] = 1
除外
S[i,j,k,l] = S[i-1,j,k,l] + S[i-1,j-w[i],k-val[i],l-1]
精确使用 z
项获得精确值 y
的方法数是所有 j
的 T[n,j,y,z]
的总和
观察
有很多方法可以查看这些问题并定义状态 T 和 S。这只是其中之一。实现也可以不同。维度的经验法则是 sack 中的另一个约束或项目中的维度意味着公式中的另一个维度。计算方式的经验法则是加起来而不是找到最大值。
【讨论】:
第二个问题 q 调用“数字...(例如 8)”。您可以通过将k
限制在 0 .. q-1 范围内并对 k
mod q 执行所有算术运算来节省第二个 DP 中的内存。
很好的答案...尽管请您解释一下最后一行...我不明白S[i,j,k,l] = S[i-1,j,k,l] + S[i-1,j-w[i],k-val[i],l-1]
如何计算方式总数....据我了解,您做了[0,0,0,0] 等于 1,因此每当达到该状态时,计数的数量就会增加,但我不确定我是否正确。加上T[ ]
和S[ ]
有什么区别,第二个问题没有提到T[ ]
...?
S[i,j,k,l]
要么有 i
-th 项目,要么没有。到达状态 (i,j,k,l) 的方式数是使用i
-th 项到达那里的方式数加上不使用i
-th 项到达那里的方式数.计数问题不关心最大化值(T),只关心获得特定值的方法的数量,这就是为什么值是一个维度。以上是关于我如何解决 0-1 背包算法的这些变体?的主要内容,如果未能解决你的问题,请参考以下文章