Knapsack Problem은 주어진 물건들의 가치와 무게, 그리고 한정된 무게의 가방을 가지고 가치의 총합을 최대화하는 문제입니다. 이 문제는 0-1 Knapsack과 Fractional Knapsack 두 가지 주요한 변형이 있습니다.
0-1 Knapsack using Dynamic Programming
def knapSack(W, wt, val, n):
dp = [[0 for x in range(W + 1)] for x in range(n + 1)]
for i in range(n + 1):
for w in range(W + 1):
if i == 0 or w == 0:
dp[i][w] = 0
elif wt[i-1] <= w:
dp[i][w] = max(val[i-1] + dp[i-1][w-wt[i-1]], dp[i-1][w])
else:
dp[i][w] = dp[i-1][w]
return dp[n][W]
val = [60, 100, 120]
wt = [10, 20, 30]
W = 50
n = len(val)
print(knapSack(W, wt, val, n))
Fractional Knapsack using Greedy
def fractional_knapsack(value, weight, capacity):
index = list(range(len(value)))
ratio = [v/w for v, w in zip(value, weight)]
index.sort(key=lambda i: ratio[i], reverse=True)
max_value = 0
fractions = [0]*len(value)
for i in index:
if weight[i] <= capacity:
fractions[i] = 1
max_value += value[i]
capacity -= weight[i]
else:
fractions[i] = capacity/weight[i]
max_value += value[i]*capacity/weight[i]
break
return max_value, fractions
value = [60, 100, 120]
weight = [10, 20, 30]
capacity = 50
print(fractional_knapsack(value, weight, capacity))
Knapsack 문제는 최적화 문제를 모델링하는 데 자주 사용되므로 이해하고 있으면 많은 문제에 적용할 수 있습니다. 다이나믹 프로그래밍과 그리디 알고리즘이 모두 활용되기 때문에 알고리즘 스터디에도 좋은 대상입니다.