관리 메뉴

오늘도 배운다

SKU Consolidation (3) - 선정 된 박스 간 통합 최적화 방법론 본문

생각/글또

SKU Consolidation (3) - 선정 된 박스 간 통합 최적화 방법론

LearnerToRunner 2024. 2. 18. 15:39

SKU Consolidation 3부를 이어 씁니다.

 

지난 글 소개

https://learn-and-run.tistory.com/216

https://learn-and-run.tistory.com/217

 

 

이번 글 개요

  • 선정된 박스 내 제품을 어떻게 통합할 것인가?
  • 가장 효과적인 통합 시나리오를 어떻게 찾을 것인가?

 

 

선정된 박스(=로케이션) 간 통합하는 방법

 

통상적으로 SKU Consolidation의 목표는 아래와 같을 것이다:

  • 로케이션 당 보관량 극대화
  • 로케이션 당 보관 스큐 최소화
  • 빈 로케이션 확보 최대화

 

따라서 박스간 통합의 효과는 아래 지표를 통해 측정할 수 있다:

  • 로케이션 당 목표 보관량을 달성한 박스의 수
  • 로케이션 당 목표 보관 스큐 수를 달성한 박스의 수
  • 통합 결과 발생한 빈 박스 수

 

그렇다면 어떻게 효과적인 통합을 이룰 것인가? 작업 대상 전체 스큐와 양을 확인하고 제품 별 목표 보관량 달성에 할애할 수량과 나머지를 구한다. 아래 예를 들어보자.

작업 대상 SKU 및 총 수량 데이터 예시

 

제품 A의 경우 한 박스에 100개를 넣을 수 있다. 따라서 우리는 A로만 가득채운 박스 5개를 만들기 위해 500개를 할당하면 48개가 남는다.

 

이렇게 한 제품으로 가득찬 박스를 만듦으로써 아래와 같이 모든 목표를 성취할 수 있다:

  • 보관량 100% 달성한 로케이션 증가
  • 한 제품으로만 구성된 로케이션 증가
  • 통합 수량 증가로 빈 로케이션 발생 가능성 증가

 

아래 제품 A 예시를 데이터로 확인해보자.

선정된 로케이션 내 A 제품의 분포 데이터 예시

 

제품 A 548개는 현재 10개 로케이션에 분포되어있다. 제품 A를 100개 단위로 통합한다면 그 결과는 다음과 같다:

  • 제품 A만으로 목표 보관량 (100%) 달성한 로케이션 수: 5
  • 제품 A 나머지 48개를 보관할 로케이션 수: 1
  • A제품을 보관한 로케이션 수: 10 ▶ 6 (-4)

이제는 full cartons를 만들고 남은 제품을 한 로케이션에 배정할 수 있다. 하지만 상황에 따라, 한 로케이션에 여러 제품을 넣더라도 보관량을 극대화해야 할 상황이 있을 수 있다. (예. 가용 공간이 없는 센터)

 

가장 효과적인 통합 시나리오 선정 방법

나머지 제품을 어떻게 효과적으로 통합할 수 있을까? 각 제품별 수량의 combinations를 통해 목표 보관량을 극대화 하는 조합을 선택하면 된다. 예를 들어보자.

 

9개의 제품에 대한 데이터 예시 (총 갯수 401개)

 

401개를 한 박스에 모두 넣으면 5개의 박스로 줄일 수 있겠지만 박스 당 스큐수 제한을 고려해야한다. 그렇다면 스큐 수 제한을 기반으로 어떻게 최적의 통합 시나리오를 찾을 수 있을까?

 

가지고 있는 제품 수와 제품 당 스큐 수를 n, r라 하자.

combination 공식

 

만약 한 로케이션에 최대 4개까지는 넣을 수 있는 상황이라면? 아래와 같이 2개, 3개, 4개씩 뽑는 경우의 수를 검토해보면 된다:

  • C(9, 2), C(9, 3), C(9, 4)

모든 경우의 수를 반복하며 100이 넘는 경우가 있을 경우는 제외한다. 제외한 후 나머지 조합에서 목표수량 100개에 가장 근접한 조합을 채택하면 된다. 이를 파이썬으로 다음과 같이 구현할 수 있다:

import pandas as pd
from itertools import combinations

# 데이터 프레임 내 SKU, QTY를 튜플화
items = list(df[['SKU', 'QTY']].itertuples(index=False, name=None))

# 모든 경우의 수 산출
all_combinations = list(combinations(items, limit_sku))

# 총 수량 100을 초과하는 조합 제외
filtered_combinations = [combo for combo in all_combinations if sum(qty for _, qty in combo) <= 100]

# 목표 타겟과 차이 순으로 정렬, 이제 100을 초과하는 조합은 제외됨
sorted_combinations = sorted(filtered_combinations,
                             key=lambda combo: (abs(100 - sum(qty for _, qty in combo)), -len(combo)))

 

 

위 코드를 토대로 박스당 스큐 수 (limit_sku)에 따라 시나리오를 다양화한다면 더 보다 나은 시나리오를 채택할 수 있다. 예를 들어보자.

토트 당 스큐 수에 따른 각 시나리오의 분류 결과

 

  • 1 SKU per tote = 9개의 토트, 100개 달성토트 0
  • 2 SKUs per tote = 4개의 토트 , 100개 달성토트 0
  • 3 SKUs per tote = 3개의 토트 , 100개 달성토트 1
  • 4 SKUs per tote = 3개의 토트 , 100개 달성토트 0

limit_sku가 3, 4일 때 토트 수가 3개로 가장 적다.또한 3인 경우 목표 보관량 100개를 달성한 박스도 생긴다. 따라서, 박스 당 스큐를 세개를 기반으로한 시나리오를 채택하면 된다.

 

한편으로는 나머지 박스가 반드시 100개가 될 필요가 없을 수도 있다. 이럴 경우, 목표 수량을 parameter를 다양화하여 보다 많은 시나리오를 검토하며 최적의 조합을 찾을 수 있다.

 

 

실제 한 센터의 데이터에 적용한 결과는 아래와 같았다:

  • 박스 수 변화: 100 ▶ 68 (-32)
  • 목표보관량(100%) 박스 수: 0 ▶ 50개
  • 박스 간 이동 횟수: 152회
  • 총 이동된 유닛 수 523개 (1,395개 중)
728x90
Comments