생산계획문제#

생산계획문제(production planning problem)는

이강우 & 김정자. (2012). EXCEL 2010 경영과학. 한경사, 217.

D부품회사는 자동차 부품을 생산하여 A자동차회사에 납품하고 있는 회사이다. A자동차회사는 분기별로 다음 분기에 사용할 부품 1과 부품 2를 D부품회사에 주문하고 있다. D부품회사는가 A자동차회사로부터 받은 이번 분기의 부품 1과 부품 2의 월별 주문수량은 Table 1과 같다.

Table 1 주문량

부품

1월

2월

3월

부품 1

3000

2500

3000

부품 2

2500

2000

2000

현재 D부품회사에서 보유하고 있는 부품 1과 부품 2의 재고는 두 부품 모두 500개씩이고 D부품회사는 3월말에도 두 부품 모두 500개 이상의 재고를 보유하려고 한다. 한편 D부품회사의 재고보관능력은 부품의 종류에 상관없이 월 2,000개이다. 그리고 부품 1과 부품 2의 1단위 생산에 소요되는 기계가공시간과 노동시간은 Table 2와 같으며 생산자원인 기계가공시간과 노동시간의 월별 가용시간은 Table 3과 같다.

Table 2

부품

Machining times per unit

Labor hours per unit

부품 1

0.2

0.05

부품 2

0.1

0.04

Table 3

Availability of machining times

Availability of labor hours

1월

1000

300

2월

1000

300

3월

1000

300

한편 부품 1과 부품 2의 총 생산비용은 생산비용, 재고유지비용, 생산량 변동에 따른 비용으로 구성되어 있으며 부품 1과 부품 2의 단위당 생산비용과 단위당 월간 재고유지비용은 Table 4와 같다.

1월

2월

3월

30

35

30

0.3

0.3

0.3

20

25

20

0.15

0.15

0.15

또한 월별 총 생산량의 변동에 따른 비용은 부품 1과 부품 2의 월 생산량의 합이 직전 월의 생산량에 비해 1개 증가할 경우에는 500원, 1개 감소할 경우에는 200원의 비용이 발생한다고 한다. 전년도 12월에는 부품 1과 부품 2를 5,000개 생산하였다고 한다. D부품회사의 총 생산비용을 최소로 하는 1월, 2월 3월의 생산계획을 수립하라.

import os
import sys

# Add the parent directory for importing custom library
sys.path.insert(0, os.path.abspath(os.path.join(os.getcwd(), os.pardir)))

Optimization with PuLP#

각 의사결정변수 및 매개변수를 선언할 때, ₩string₩과 ₩dictionary₩를 사용하면 전체적인 분위기가 다음과 같아진다. 다음은 기말재고량을 구하는 공식을 표현한 것이다. 두 개의 코드를 보고 앞으로 수리적 모형을 파이썬으로 구현할 때 참고하도록 하자. 본인은 후자를 좋아한다.

from pulp import *

parts = ['P1', 'P2']
month = ['Jan', 'Feb', 'Mar']

demand = {'P1': [3000, 2500, 3000], 
          'P2': [2500, 2000, 2000]}

prob = LpProblem('Production Planning', LpMinimize)

indexs = [(p, m) for p in parts for m in month]

X = LpVariable.dicts('X', indexs, lowBound=0)
Y = LpVariable.dicts('Y', indexs, lowBound=0)

# Inital inventory level
for p in parts:
    prob += X[p, 'Jan'] - Y[p, 'Jan'] == demand[p][month.index('Jan')] - 500

# Expected ending inventory level
for p in parts:
    for m in month:
        if m != 'Jan':
            prob += X[p, m] + Y[p, month[month.index(m)-1]] - Y[p, m] == demand[p][month.index(m)]
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
Cell In[2], line 1
----> 1 from pulp import *
      3 parts = ['P1', 'P2']
      4 month = ['Jan', 'Feb', 'Mar']

ModuleNotFoundError: No module named 'pulp'
prob
Production Planning:
MINIMIZE
None
SUBJECT TO
_C1: X_('P1',_'Jan') - Y_('P1',_'Jan') = 2500

_C2: X_('P2',_'Jan') - Y_('P2',_'Jan') = 2000

_C3: X_('P1',_'Feb') - Y_('P1',_'Feb') + Y_('P1',_'Jan') = 2500

_C4: X_('P1',_'Mar') + Y_('P1',_'Feb') - Y_('P1',_'Mar') = 3000

_C5: X_('P2',_'Feb') - Y_('P2',_'Feb') + Y_('P2',_'Jan') = 2000

_C6: X_('P2',_'Mar') + Y_('P2',_'Feb') - Y_('P2',_'Mar') = 2000

VARIABLES
X_('P1',_'Feb') Continuous
X_('P1',_'Jan') Continuous
X_('P1',_'Mar') Continuous
X_('P2',_'Feb') Continuous
X_('P2',_'Jan') Continuous
X_('P2',_'Mar') Continuous
Y_('P1',_'Feb') Continuous
Y_('P1',_'Jan') Continuous
Y_('P1',_'Mar') Continuous
Y_('P2',_'Feb') Continuous
Y_('P2',_'Jan') Continuous
Y_('P2',_'Mar') Continuous
from pulp import *

parts = 2
month = 3

demand = [[3000, 2500, 3000], 
          [2500, 2000, 2000]]

prob = LpProblem('Production Planning', LpMinimize)

indexs = [(i, j) for i in range(parts) for j in range(month)]

X = LpVariable.dicts('X', indexs, lowBound=0)
Y = LpVariable.dicts('Y', indexs, lowBound=0)

# Inital inventory level
for i in range(parts):
    prob += X[i, 0] - Y[i, 0] == demand[i][0] - 500

# Expected ending inventory level
for i in range(parts):
    for j in range(1, month):
        prob += X[i, j] + Y[i, j-1] - Y[i, j] == demand[i][j]
prob
Production Planning:
MINIMIZE
None
SUBJECT TO
_C1: X_(0,_0) - Y_(0,_0) = 2500

_C2: X_(1,_0) - Y_(1,_0) = 2000

_C3: X_(0,_1) + Y_(0,_0) - Y_(0,_1) = 2500

_C4: X_(0,_2) + Y_(0,_1) - Y_(0,_2) = 3000

_C5: X_(1,_1) + Y_(1,_0) - Y_(1,_1) = 2000

_C6: X_(1,_2) + Y_(1,_1) - Y_(1,_2) = 2000

VARIABLES
X_(0,_0) Continuous
X_(0,_1) Continuous
X_(0,_2) Continuous
X_(1,_0) Continuous
X_(1,_1) Continuous
X_(1,_2) Continuous
Y_(0,_0) Continuous
Y_(0,_1) Continuous
Y_(0,_2) Continuous
Y_(1,_0) Continuous
Y_(1,_1) Continuous
Y_(1,_2) Continuous
from pulp import *

parts = 2
month = 3

demand = [[3000, 2500, 3000], 
          [2500, 2000, 2000]]

prod = [0.2, 0.1]
labo = [0.05, 0.04]

avail_prod = [1000, 1000, 1000]
avail_labo = [300, 300, 300]

p1_prod = [30, 35, 30]
p1_inve = [0.3, 0.3, 0.3]

prob = LpProblem('Production Planning', LpMinimize)

indexs = [(i, j) for i in range(parts) for j in range(month)]

X = LpVariable.dicts('X', indexs, lowBound=0)
Y = LpVariable.dicts('Y', indexs, lowBound=0)

# Inital inventory level
for i in range(parts):
    prob += X[i, 0] - Y[i, 0] == demand[i][0] - 500

# Expected ending inventory level
for i in range(parts):
    for j in range(1, month):
        prob += X[i, j] + Y[i, j-1] - Y[i, j] == demand[i][j]