민감도 분석#

민감도 분석(sensitivity analysis)

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

D전자는 통신장비를 생산하여 판매하고 있는 회사이며 최근 개발한 신제품의 판매시장을 국내, 아시아지역, 유럽지역으로 확장하려고 한다. 이를 위하여 각 지역별 시장조사를 한 결과 수집된 자료는 표 1와 같다.

Table 1 D전자의 마케팅자료

지역

단위당 판매이익(만원)

단위당 광고비용(만원)

단위당 판매활동시간(시간)

국내

6

1.0

1.5

아시아

4

0.8

2.0

유럽

7

1.5

3.0

D전자의 신제품 생산능력은 1개월에 3,500개이고 1개월 동안 아시아 지역에 최소한 500개를 공급할 계획을 가지고 있다. 그리고 D전자의 판매원의 판매활동시간은 1개월에 총 5,000시간이며 1개월 광고비 예산은 3,000만원이다. 한편 D전자는 주문생산을 원칙으로 하고 있기 대문에 재고는 보유하지 않는다. D전자의 월 판매이익을 최대로 하는 지역별 신제품의 판매량을 구하기 위한 선형계획 모형을 작성하여 지역별 최적 판매계획을 수립하고 민감도분석을 수행하라.

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#

from pulp import *

# Define problem
prob = LpProblem(name='Marketing', sense=LpMaximize)

# Create decision variables and non-negative constraint
x1 = LpVariable(name='X1', lowBound=0, upBound=None, cat='Continuous')
x2 = LpVariable(name='X2', lowBound=0, upBound=None, cat='Continuous')
x3 = LpVariable(name='X3', lowBound=0, upBound=None, cat='Continuous')

# Set objective function
prob += 6*x1 + 4*x2 + 7*x3

# Set constraints
prob += 1.0*x1 + 0.8*x2 + 1.5*x3 <= 3000
prob += 1.5*x1 + 2.0*x2 + 3.0*x3 <= 5000
prob += x1 + x2 + x3 <= 3500
prob += x2 >= 500

# Solving problem
prob.solve()
print('Status: {}'.format(LpStatus[prob.status]))
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
Cell In[2], line 1
----> 1 from pulp import *
      3 # Define problem
      4 prob = LpProblem(name='Marketing', sense=LpMaximize)

ModuleNotFoundError: No module named 'pulp'
print('Z = {}'.format(value(prob.objective)))
for v in prob.variables():
    print('{} = {}\tReduced cost {}'.format(v.name, v.varValue, v.dj))
Z = 17600.0
X1 = 2600.0	Reduced cost 0.0
X2 = 500.0	Reduced cost -8.8817842e-16
X3 = 0.0	Reduced cost -2.0
print('Sensitivity Analysis\nConstraint\tShadow Price\tSlack')
for name, c in prob.constraints.items():
    print('{}: \t\t{}\t\t{}'.format(name, c.pi, c.slack))
Sensitivity Analysis
Constraint	Shadow Price	Slack
_C1: 		6.0		-0.0
_C2: 		-0.0		100.0
_C3: 		-0.0		400.0
_C4: 		-0.8		-0.0

Optimization with GUROBI#

from gurobipy import *
from ortools.utils import set_gurobi, custom_callback

# Create a new model
m = Model(name='Marketing')

# Create variables
x1 = m.addVar(lb=0, ub=1e+100, vtype=GRB.CONTINUOUS, name='X1')
x2 = m.addVar(lb=0, ub=1e+100, vtype=GRB.CONTINUOUS, name='X2')
x3 = m.addVar(lb=0, ub=1e+100, vtype=GRB.CONTINUOUS, name='X3')

# Set objective
m.setObjective(6*x1 + 4*x2 + 7*x3, sense=GRB.MAXIMIZE)

# Add constraint
m.addConstr(1.0*x1 + 0.8*x2 + 1.5*x3 <= 3000)
m.addConstr(1.5*x1 + 2.0*x2 + 3.0*x3 <= 5000)
m.addConstr(x1 + x2 + x3 <= 3500)
m.addConstr(x2 >= 500)

set_gurobi(m, verbose=False)

# Optimize model
m.optimize(custom_callback)
if m.status == GRB.Status.OPTIMAL:
    print('Status: Optimal')
Status: Optimal
print('Z = {}'.format(m.objVal))
for v in m.getVars():
    print('{} = {}\tReduced cost {}'.format(v.varName, v.x, v.RC))
Z = 17600.0
X1 = 2600.0	Reduced cost 0.0
X2 = 500.0	Reduced cost 0.0
X3 = 0.0	Reduced cost -2.0
print('Sensitivity Analysis\nConstraint\tShadow Price\tSlack')
for c in m.getConstrs():
    print('{}: \t\t{}\t\t{}'.format(c.ConstrName, c.Pi, c.Slack))
Sensitivity Analysis
Constraint	Shadow Price	Slack
R0: 		6.0		0.0
R1: 		0.0		100.0
R2: 		0.0		400.0
R3: 		-0.8000000000000007		0.0