个人主页:丷从心
系列专栏:回溯法
max ? ∑ i = 1 n v i x i { ∑ i = 1 n w i x i ≤ c x i ∈ { ? 0 , 1 ? } ( 1 ≤ i ≤ n ) \max\displaystyle\sum\limits_{i = 1}^{n}{v_{i} x_{i}} \kern{2em} \begin{cases} \displaystyle\sum\limits_{i = 1}^{n}{w_{i} x_{i} \leq c} \\ x_{i} \in \set{0 , 1} (1 \leq i \leq n) \end{cases} maxi=1∑n?vi?xi?? ? ??i=1∑n?wi?xi?≤cxi?∈{0,1}(1≤i≤n)?
Python
实现def backtrack_knapsack(values, weights, capacity):
n = len(values)
best_solution = []
best_value = 0
def constraint(weight):
# 约束函数: 检查当前解是否满足容量限制
return weight <= capacity
def bound(weight, value, index):
# 限界函数: 计算当前解的价值总和加上剩余物品价值作为上界, 用于剪枝
bound = value
remaining_capacity = capacity - weight
remaining_weights = weights[index + 1:]
remaining_values = values[index + 1:]
while index + 1 < n and weights[index + 1] <= remaining_capacity:
bound += value[index + 1]
return total_weight
def backtrack(solution, weight, value, index):
nonlocal best_solution, best_value
if index == n:
# 已经遍历完所有物品
if value > best_value:
# 如果当前解的价值更大, 更新最优解
best_solution = solution
best_value = value
return
# 尝试选择当前物品
weight += weights[index]
value += values[index]
if constraint(weight):
# 如果满足约束函数, 继续探索下一个物品
backtrack(solution + [1], weight, value, index + 1)
weight -= weights[index]
value -= values[index]
# 尝试不选择当前物品
if bound(weight, value, index) >= best_value:
# 如果当前解的上界仍然可能更好, 继续探索下一个物品
backtrack(solution + [0], weight, value, index + 1)
backtrack([], [], 0, 0)
return best_solution, best_value
values = [60, 100, 120]
weights = [10, 20, 30]
capacity = 50
best_solution, best_value = backtrack_knapsack(values, weights, capacity)
print(f'最优解: {best_solution}')
print(f'最优值: {best_value}')