본문 바로가기
Analysis/Example

물류 네트워크 설계 - 생산 계획

by 5ole 2021. 2. 18.

1. 전제조건 

 

  • 어떤 제품을 얼마나 만들 것인지 생산 계획

2021/02/15 - [Data/Data Analysis] - 물류 네트워크 설계 - 최적화 라이브러리

 

물류 네트워크 설계 - 최적화 라이브러리

1. 전제조건 제품 판매하는 대리점 P, Q 판매되는 상품 A, B 상품 일정 수요 예측해 공장 X, Y 에서 생산 제품마다, 공장마다 다른 생산라인 레인 0, 1 공장에서 대리점까지 운송비, 제고 비용 등 고려

5ohyun.tistory.com

 

2. 데이터 정보

 

  • product_plan_material.csv : 제품 제조에 필요한 원료 비율 - 제품 2개, 원료 3개
  • product_plan_profit.csv : 제품 이익 - 제품 2개
  • product_plan_stock.csv : 원료 재고 - 원료 3개
  • product_plan.csv : 제품 생산량 - 제품 2개, 제품 1만 생산중
import os
import pandas as pd
import matplotlib.pyplot as plt

os.chdir('C:\\Users\\leeso\\Downloads\\pyda100-master\\3장')

use_log=pd.read_csv('use_log.csv')
customer=pd.read_csv('customer.csv')

 

 

 

3.  생산계획 최적화

 

(1) 목적함수 - 이익 계산 함수

 

  • 각 제품의 이익과 생산량과의 곱의 합
def product_plan(df_profit,df_plan):
    profit = 0
    for i in range(len(df_profit.index)):
        for j in range(len(df_plan.columns)):
            profit += df_profit.iloc[i][j]*df_plan.iloc[i][j]
    return profit

product_plan(df_profit,df_plan)

 

 

(2) 이익 함수의 최대화

 

  • model_max로 최대화 계산
df = df_material.copy()
inv = df_stock

m = model_max()

v1 = {(i):LpVariable('v%d'%(i),lowBound=0) for i in range(len(df_profit))}
# 제품 수와 같은 차원으로 정의

m += lpSum(df_profit.iloc[i]*v1[i] for i in range(len(df_profit)))
# v1과 제품별 이익의 곱의 합으로 목적함수 정의

for i in range(len(df_material.columns)):
    m += lpSum(df_material.iloc[j,i]*v1[j] for j in range(len(df_profit)) ) <= df_stock.iloc[:,i]
# 제약조건 정의 - 재고를 넘지않게
    
    
m.solve() # 최적화 문제

df_plan_sol = df_plan.copy()

for k,x in v1.items():
    df_plan_sol.iloc[k] = value(x) # 최적화한 값
    
df_plan_sol  
  
value(m.objective) # 총 이익

 

 

(3) 제약 조건

 

  • 각 원료의 사용량
  • 재고에 맞게 효율적으로 이용
  • 제품 생산량, 원료, 재고 데이터 사용
def condition_stock(df_plan,df_material,df_stock):
    flag = np.zeros(len(df_material.columns))
    for i in range(len(df_material.columns)):  # 원료
        temp_sum = 0
        for j in range(len(df_material.index)):  # 제품
            temp_sum = temp_sum + df_material.iloc[j][i]*float(df_plan.iloc[j]) # 필요한 원료 개수
        if (temp_sum<=float(df_stock.iloc[0][i])):
            flag[i] = 1
            
        print(df_material.columns[i]+"  사용량:"+str(temp_sum)+", 재고:"+str(float(df_stock.iloc[0][i])))
    return flag

print("제약 조건 계산 결과:"+str(condition_stock(df_plan_sol,df_material,df_stock)))

 

 

4. 물류 네트워크 설계

 

  • 운송 비용과 제조 비용이 수요량을 맞추며 최소가 되도록
  • 목적함수는 운송 비용과 제조비용의 합
  • 제약 조건은 각 대리점의 판매 수가 수요 수를 넘도록 정의
import numpy as np
import pandas as pd

제품 = list('AB')
대리점 = list('PQ')
공장 = list('XY')
레인 = (2,2)

# 운송비 #
tbdi = pd.DataFrame(((j,k) for j in 대리점 for k in 공장), columns=['대리점','공장'])
tbdi['운송비'] = [1,2,3,1]
print(tbdi)

# 수요 #
tbde = pd.DataFrame(((j,i) for j in 대리점 for i in 제품), columns=['대리점','제품'])
tbde['수요'] = [10,10,20,20]
print(tbde)

# 생산 #
tbfa = pd.DataFrame(((k,l,i,0,np.inf) for k,nl in zip (공장,레인) for l in range(nl) for i in 제품), 
                    columns=['공장','레인','제품','하한','상한'])
tbfa['생산비'] = [1,np.nan,np.nan,1,3,np.nan,5,3]
tbfa.dropna(inplace=True)
tbfa.loc[4,'상한']=10
print(tbfa)

from ortoolpy import logistics_network
_, tbdi2, _ = logistics_network(tbde, tbdi, tbfa,dep = "대리점", dem = "수요",fac = "공장",
                                prd = "제품",tcs = "운송비",pcs = "생산비",lwb = "하한",upb = "상한")

print(tbfa)
print(tbdi2)

 

5.

tbdi2 = tbdi2[["공장","대리점","운송비","제품","VarX","ValX"]]
tbdi2

trans_cost = 0
for i in range(len(tbdi2.index)):
    trans_cost += tbdi2["운송비"].iloc[i]*tbdi2["ValX"].iloc[i]
print("총 운송비:"+str(trans_cost))
product_cost = 0
for i in range(len(tbfa.index)):
    product_cost += tbfa["생산비"].iloc[i]*tbfa["ValY"].iloc[i]
print("총 생산비:"+str(product_cost))

 

+ 참고 자료 및 출처

 

 

 

댓글