프로그래밍/알고리즘
[Python] 배송비 절약 문제 동적프로그래밍 구현
상어군
2022. 9. 22. 11:09
반응형
이번 글에서는 파이썬 언어를 사용하여 배송비 절약 문제를 구현합니다.
이때 동적프로그래밍 기법을 사용합니다.
1. 배송비 절약 문제
물건의 개수, 배송가능한 무게제한, 물건의 무게와 가치가 주어졌을 때,
한번에 배송할 수 있는 최대의 물건 가치가 얼마인지 구하시오.
2. 코드 구현
주어지는 입력 정보
# 물건 개수
item_num = 5
# 배송 제한 무게
limit_weight = 10
# 물건의 무게
w_lst = [2,1,1,4,4]
# 물건의 가치
v_lst = [34,686,668,678,560]
배송 가능 최대 물건 가치 저장 리스트 생성
D = [[0]*(limit_weight+1) for _ in range(item_num)]
물건별로 탐색하며 0~배송 제한 무게값 별로 최대 가치를 계산
배송 제한 무게가 10일경우 0~9 무게에 대한 최대 배송 가치를 계산하는 이유는,
이후 물건이 무게가 3일경우 비게되는 무게 7에 대해서 가장 높은 가치를 가지는 값을 찾기 위해서이다.
for item_n in range(item_num):
# 현재 물건의 무게와 가치 받아오기
now_item_w, now_item_v = w_lst[item_n-1],v_lst[item_n-1] # 물건1번의 인덱스는 0이기에 -1 취하기
# 무게0 부터 무게 리미트까지 순차로 증가하면서 item이 들어갈 수 있나 검사
for weight_x in range(limit_weight+1): # 무게 n까지 검사해야해서 +1 취하기
# 아이템의 무게가 조건 무게보다 크다면
# 이전 물건의 값 계승
if now_item_w > weight_x:
if item_n != 0: # 아이템 번호가 0일경우 무시(계승할 이전 물건이 없음)
D[item_n][weight_x] = D[item_n-1][weight_x]
else: # 아이템의 무게보다 조건 무게가 크거나 같다면
if item_n == 0: # 첫 물건(인덱스0)일 경우는 그 물건의 가치 삽입
tmp = now_item_v
else: # "이전 물건 가치" "현재 물건 가치+남은무게의 이전물건 가치" 중 큰것 삽입
tmp = max(D[item_n-1][weight_x], D[item_n-1][weight_x-now_item_w]+now_item_v)
D[item_n][weight_x] = tmp
3. 코드 종합
# 중간 과정을 점검하기 위한 프린트 코드
# 실제로 짜실때는 해당 구문을 삭제하세요
def print_m(m):
for x in m:
print(x)
print()
# 물건 개수, 무게 제한, 물건 무게 리스트, 물건 가치 리스트
def func(item_num,limit_weight,w_lst,v_lst):
# 배송가능한 최대가치 저장용 이중리스트
D = [[0]*(limit_weight+1) for _ in range(item_num)]
print_m(D) # 진행과정 출력해보기 => 추후 삭제 필요
# 각 물건별로 탐색
for item_n in range(item_num):
# 현재 물건의 무게와 가치 받아오기
now_item_w, now_item_v = w_lst[item_n-1],v_lst[item_n-1] # 물건1번의 인덱스는 0이기에 -1 취하기
# 무게0 부터 무게 리미트까지 순차로 증가하면서 item이 들어갈 수 있나 검사
for weight_x in range(limit_weight+1): # 무게 n까지 검사해야해서 +1 취하기
# 아이템의 무게가 조건 무게보다 크다면
# 이전 물건의 값 계승
if now_item_w > weight_x:
if item_n != 0: # 아이템 번호가 0일경우 무시(계승할 이전 물건이 없음)
D[item_n][weight_x] = D[item_n-1][weight_x]
else: # 아이템의 무게보다 조건 무게가 크거나 같다면
if item_n == 0: # 첫 물건(인덱스0)일 경우는 그 물건의 가치 삽입
tmp = now_item_v
else: # "이전 물건 가치" "현재 물건 가치+남은무게의 이전물건 가치" 중 큰것 삽입
tmp = max(D[item_n-1][weight_x], D[item_n-1][weight_x-now_item_w]+now_item_v)
D[item_n][weight_x] = tmp
print_m(D)
# 저장용 이중리스트의 마지막 값(모든 셀에 대해서 계산된 가장 큰 값이다) 반환
return D[-1][-1]
### 코드 메인 ###
item_num = 5
limit_weight = 10
w_lst = [2,1,1,4,4]
v_lst = [34,686,668,678,560]
print(func(item_num,limit_weight,w_lst,v_lst))
반응형