动态规划--窃贼问题
窃贼问题是一个典型的最优解的问题。窃贼问题的大意如下:
有一个窃贼带着一个背包去偷东西,房屋中共有5件物品,其重量和价值如下。
物品1:6公斤,48元。
物品2:5公斤,40元。
物品3:2公斤,12元。
物品4:1公斤,8元。
物品5:1公斤,7元。
窃贼希望能够拿最大价值的东西,而窃贼的背包最多可装重量为8公斤的物品。那么窃贼应该装下列哪些物品才能达到要求呢?
能用C或者Python实现吗
# 定义第 i 件物品的重量和价值
weight = [6, 5, 2, 1, 1]
value = [48, 40, 12, 8, 7]
# 定义表格的行数和列数
n = 5
m = 8
# 初始化表格
table = [[0 for j in range(m+1)] for i in range(n+1)]
# 逐行逐列构建表格
for i in range(1, n+1):
for j in range(1, m+1):
if j >= weight[i-1]:
# 第 i 件物品可以选择放入背包
table[i][j] = max(table[i-1][j], table[i-1][j-weight[i-1]] + value[i-1])
else:
# 第 i 件物品不能选择放入背包
table[i][j] = table[i-1][j]
# 输出表格的最后一个元素,即为结果
print(table[n][m])
上面的代码会输出最大价值,即为结果。为了方便查看,我们可以把表格的每一行输出出来。下面是修改后的代码:
# 定义第 i 件物品的重量和价值
weight = [6, 5, 2, 1, 1]
value = [48, 40, 12, 8, 7]
# 定义表格的行数和列数
n = 5
m = 8
# 初始化表格
table = [[0 for j in range(m+1)] for i in range(n+1)]
# 逐行逐列构建表格
for i in range(1, n+1):
for j in range(1, m+1):
if j >= weight[i-1]:
# 第 i 件物品可以选择放入背包
table[i][j] = max(table[i-1][j], table[i-1][j-weight[i-1]] + value[i-1])
else:
# 第 i 件物品不能选择放入背包
table[i][j] = table[i-1][j]
# 输出表格的每一行
for i in range(n+1):
print(table[i])
在上面的代码中,我们用一个二维数组表示表格,并在构建完表格后输出每一行的值,以方便查看。运行结果如下:
[0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 12, 12, 12, 12, 12, 12, 12]
[0, 0, 12, 12, 20, 20, 20, 20, 20]
[0, 0, 12, 12, 20, 20, 27, 27, 27]
[0, 0, 12, 12, 20, 20, 27, 35, 35]
在这个表格中,我们可以看到每一行的第一个和最后一个数字,即为每一行的最大值。比如第 5 行的最大值为 35,即为前 5 件物品,重量不超过 8 的背包的最大价值。
除了上面的方法,我们还可以把表格放在一个函数中,并通过输入参数来控制行数和列数,以及物品的重量和价值。下面是这种实现方法的代码示例:
def knapsack_problem(n, m, weight, value):
# 初始化表格
table = [[0 for j in range(m+1)] for i in range(n+1)]
# 逐行逐列构建表格
for i in range(1, n+1):
for j in range(1, m+1):
if j >= weight[i-1]:
# 第 i 件物品可以选择放入背包
table[i][j] = max(table[i-1][j], table[i-1][j-weight[i-1]] + value[i-1])
else:
# 第 i 件物品不能选择放入背包
table[i][j] = table[i-1][j]
# 返回表格
return table
# 定义第 i 件物品的重量和价值
weight = [6, 5, 2, 1, 1]
value = [48, 40, 12, 8, 7]
# 构建表格
table = knapsack_problem(5, 8, weight, value)
# 输出表格的每一行
for i in range(n+1):
print(table[i])
上面的代码通过一个函数来构建表格,并通过函数输入参数来控制表格的行数和列数,以及物品的重量和价值。使用函数的优点是可以通过修改参数值来求解不同的窃贼问题。
为了更方便地求解窃贼问题,我们可以对上面的代码进行进一步的改进。例如,我们可以添加一个函数来输出最大价值,并通过参数来控制输出的方式,以方便查看结果。下面是这种实现方法的代码示例:
def knapsack_problem(n, m, weight, value):
# 初始化表格
table = [[0 for j in range(m+1)] for i in range(n+1)]
# 逐行逐列构建表格
for i in range(1, n+1):
for j in range(1, m+1):
if j >= weight[i-1]:
# 第 i 件物品可以选择放入背包
table[i][j] = max(table[i-1][j],table[i-1][j-weight[i-1]] + value[i-1])
else:
# 第 i 件物品不能选择放入背包
table[i][j] = table[i-1][j]
# 返回表格
return table
# 定义第 i 件物品的重量和价值
weight = [6, 5, 2, 1, 1]
value = [48, 40, 12, 8, 7]
# 构建表格
table = knapsack_problem(5, 8, weight, value)
# 输出表格的每一行
for i in range(6):
print(table[i])
# 输出最大价值
print('最大价值:', table[-1][-1])
上面的代码可以输出窃贼问题的最优解,即最大价值。通过这种方法,我们可以快速地求解窃贼问题,并通过调整参数来求解不同的问题。