배낭 문제(Knapsack Problem)는 제한된 무게를 가진 배낭에 물건을 담을 때, 물건들의 가치를 최대화할 방법을 찾는 조합 최적화 문제입니다.
각 물건은 고유의 무게와 가치를 가지고 있으며, 배낭에는 정해진 무게를 초과하지 않도록 물건을 담아야 합니다.
목표는 이 제한된 무게 안에서 담을 수 있는 물건들의 가치를 최대화하는 것입니다.
배낭 문제에는 두 가지 변형이 있습니다:
1.
Fractional Knapsack 문제: 물건을 부분적으로 나눌 수 있는 경우입니다. 즉, 물건의 일부를 배낭에 넣을 수 있으며, 이때 가치와 무게는 비례하여 계산됩니다. 이 문제는 그리디 알고리즘을 통해 최적해를 쉽게 구할 수 있습니다.
2.
0-1 Knapsack 문제: 물건을 나누지 않고 그대로 넣어야 하는 경우입니다. 물건을 넣거나 넣지 않기 때문에 이진 결정을 해야 합니다. 이 문제는 동적 계획법을 통해 해결할 수 있으며, 계산 복잡도가 더 큽니다.
Knapsack 문제는 휴리스틱 방법이나 Mixed Integer Programming(MIP)을 사용해 해결할 수 있지만,
본 글에서는 Mealpy 패키지를 이용한 메타휴리스틱 방법으로 문제를 해결하는 방법을 살펴보겠습니다.
전체 소스
import numpy as np
from mealpy.physics_based import MVO
# 각 물건의 가치와 무게를 정의
VALUES = np.array([360, 83, 59, 130, 431, 67, 230, 52, 93, 125]) # 물건의 가치
WEIGHTS = np.array([7, 10, 30, 22, 80, 94, 11, 81, 70, 64]) # 물건의 무게
CAPACITY = 200 # 배낭의 최대 용량
# 변수의 하한 및 상한 정의 (각 물건이 선택될 수 있는 범위)
LB = [0] * 10 # 하한: 물건은 선택되지 않을 수도 있음 (0)
UB = [1.99] * 10 # 상한: MVO 알고리즘이 실수값을 다루므로 1.99로 설정 (0 또는 1로 매핑)
# 적합도 함수 정의
def fitness_function(solution):
"""
주어진 솔루션의 적합도를 계산하는 함수.
:param solution: MVO가 생성한 실수형 배열 (물건 선택 여부)
:return: 선택된 물건의 총 가치 (벌점 적용)
"""
# 벌점 함수: 용량 초과시 초과한 용량만큼 감산
def punish_function(value):
return 0 if value <= CAPACITY else value
# 실수형 배열을 정수형으로 변환 (0 또는 1)
solution_int = solution.astype(int)
# 현재 선택된 물건의 총 무게 계산
current_capacity = np.sum(solution_int * WEIGHTS)
# 총 가치 계산 (벌점 적용)
temp = np.sum(solution_int * VALUES) - punish_function(current_capacity)
return temp
# 최적화 문제 정의
problem_dict1 = {
"fit_func": fitness_function, # 적합도 함수
"lb": LB, # 하한
"ub": UB, # 상한
"minmax": "max", # 최대화 문제로 설정
}
# 알고리즘 설정 및 실행
model1 = MVO.OriginalMVO(epoch=100, pop_size=50) # 반복 횟수 100, 초기 집단 크기 50
best_position, best_fitness = model1.solve(problem_dict1) # 최적화 실행
# 최적화 결과 출력
print("최적 솔루션(물건 선택 여부):", model1.solution[0].astype(int)) # 0 또는 1로 변환
Python
복사
결과는 아래와 같습니다.
[1 1 0 1 1 0 1 0 1 0]
Python
복사
즉, 0번, 1번, 3번, 4번, 6번, 8번의 총 6개 아이템을 선택하여 배낭에 넣으면, 배낭의 용량(Capacity)을 초과하지 않으면서도 가장 높은 가치를 얻을 수 있습니다.
Keyword: Logistics Optimization, 물류 최적화, 파이썬, Python, 선형계획법, Linear Programming, Google OR Tools
Reference:
[1] The Knapsack Problem by Google, https://developers.google.com/optimization/pack/knapsack, Creative Commons Attribution 4.0 License
[3] Knapsack Problem by Mealpy, https://github.com/thieu1995/mealpy/blob/master/examples/applications/discrete-problems/knapsack-problem.py