Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 无界背包与经典背包的比较_C++_Algorithm_Dynamic Programming - Fatal编程技术网

C++ 无界背包与经典背包的比较

C++ 无界背包与经典背包的比较,c++,algorithm,dynamic-programming,C++,Algorithm,Dynamic Programming,我在网上读过两个截然不同的问题0-1背包问题和无界背包问题。我发现这两个问题都是通过动态规划来解决的,但有两种不同的方式。 如果用二维数组求解0-1背包问题,则无界背包问题仅使用一维数组 你可以读更多的书 正如我所知,这两个问题的区别在于0-1背包问题只包含有限数量的东西,而无界背包问题允许获取任何资源的一个或多个实例。但是,我不知道为什么它改变了解决这个问题的方式?你能告诉我原因吗?表格方法更易于解释和调试,这就是为什么算法说明通常显示这种方式 注意,对于0-1背包问题,我们必须排除重复使用物

我在网上读过两个截然不同的问题0-1背包问题无界背包问题。我发现这两个问题都是通过动态规划来解决的,但有两种不同的方式。 如果用二维数组求解0-1背包问题,则无界背包问题仅使用一维数组

你可以读更多的书


正如我所知,这两个问题的区别在于0-1背包问题只包含有限数量的东西,而无界背包问题允许获取任何资源的一个或多个实例。但是,我不知道为什么它改变了解决这个问题的方式?你能告诉我原因吗?

表格方法更易于解释和调试,这就是为什么算法说明通常显示这种方式

注意,对于0-1背包问题,我们必须排除重复使用物品两次的可能性。所以在外循环的每一步,我们都使用当前项更新以前的最佳结果

但是我们只使用表的最后一行(查看索引
i
i-1
),因此我们可以仅使用当前行和最后一行将表大小减小到
2 x容量

此外,我们可以使用一维数组的方法,应用一个技巧——为了避免重用项,我们可以执行反向遍历

下面的Python代码使用来自wiki页面的数据,并显示了表和线性数组实现

wt = [23,26,20,18,32,27,29,26,30,27]
val = [505,352,458,220,354,414,498,545,473,543]

def knap1(w,v, cap):
    n = len(w)
    m = [[0]*(cap+1) for _ in range(n)]
    for i in range(n):
        for j in range(cap + 1):
            if w[i] > j:
                m[i][j] = m[i-1][j]
            else:
                m[i][j] = max(m[i-1][j], m[i-1][j-w[i]] + v[i])
    return m[n-1][cap]

def knap2(w,v, cap):
    n = len(w)
    m = [0]*(cap+1)
    for i in range(n):
        for j in range(cap, w[i]-1,-1):
                m[j] = max(m[j], m[j-w[i]] + v[i])
    return m[cap]


print(knap1(wt, val, 67))
print(knap2(wt, val, 67))

>>1270
>>1270

表方法更易于解释和调试,这就是为什么算法说明通常显示这种方式

注意,对于0-1背包问题,我们必须排除重复使用物品两次的可能性。所以在外循环的每一步,我们都使用当前项更新以前的最佳结果

但是我们只使用表的最后一行(查看索引
i
i-1
),因此我们可以仅使用当前行和最后一行将表大小减小到
2 x容量

此外,我们可以使用一维数组的方法,应用一个技巧——为了避免重用项,我们可以执行反向遍历

下面的Python代码使用来自wiki页面的数据,并显示了表和线性数组实现

wt = [23,26,20,18,32,27,29,26,30,27]
val = [505,352,458,220,354,414,498,545,473,543]

def knap1(w,v, cap):
    n = len(w)
    m = [[0]*(cap+1) for _ in range(n)]
    for i in range(n):
        for j in range(cap + 1):
            if w[i] > j:
                m[i][j] = m[i-1][j]
            else:
                m[i][j] = max(m[i-1][j], m[i-1][j-w[i]] + v[i])
    return m[n-1][cap]

def knap2(w,v, cap):
    n = len(w)
    m = [0]*(cap+1)
    for i in range(n):
        for j in range(cap, w[i]-1,-1):
                m[j] = max(m[j], m[j-w[i]] + v[i])
    return m[cap]


print(knap1(wt, val, 67))
print(knap2(wt, val, 67))

>>1270
>>1270

@对不起,我的问题是最后一句话,我只漏掉了问号here@EricPostpischil很抱歉,我的问题是最后一句话,我只漏掉了问号。很抱歉,如果我用2D表格来解无界背包,我会采用同样的解吗?我不知道为什么,但令人惊讶的是,你的两个算法给出了相同的结果,在什么情况下会发生?对于无界背包,你需要修改表算法-例如,选择最大值不仅使用
m[I-1][j-w[I]+v[I]
单元格,而且使用
m[I-1][j-2*w[I]+2*v[I]
等等,最多使用
j/w[I]
项目。算法越复杂,速度越慢,一维算法就越好。我的两个实现给出了相同的结果,因为它们本质上代表了相同的解决方案<代码>项目0的最佳结果..i=>使用项目i+1更新,选择永久重量最大值(m[j],m[j-w[i]]+v[i])
因此我很抱歉,但是如果我应用2D表格来解决无界背包问题,我会采用相同的解决方案吗?我不知道为什么,但令人惊讶的是,你的两个算法给出了相同的结果,在什么情况下会发生?对于无界背包,你需要修改表算法-例如,选择最大值不仅使用
m[I-1][j-w[I]+v[I]
单元格,而且使用
m[I-1][j-2*w[I]+2*v[I]
等等,最多使用
j/w[I]
项目。算法越复杂,速度越慢,一维算法就越好。我的两个实现给出了相同的结果,因为它们本质上代表了相同的解决方案<代码>项目0的最佳结果..i=>使用项目i+1更新,选择永久最大重量(m[j],m[j-w[i]]+v[i])
等等