민감도 분석#
민감도 분석(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