Sensitivity analysis is the study of how the uncertainty in the
output of a mathematical model or system (numerical or otherwise) can be
apportioned to different sources of uncertainty in its inputs. We will
use the lpSolveAPI R-package as we did in the previous
lab.
In this lab assignment you are asked to first find the optimum solution for the problem defined below and then run a sensitivity analysis.
The Operations Manager of a retailer company, producing and selling jackets and parkas wants to identify the production rates for their famous jacket and parka that would maximize their profit. Based on past history he knows that per unit profits for their winter jacket and parka are $9 and $12.5, respectively.
. A medium size jacket requires 8.5 feet of fabric, while the parka requires 12.5. . The amount of machine time needed to produce a jacket is 1.5hours and 2hours for the parka. . A tailor usually spends about 2 hours on sewing and stitching for a winter jacket and about 3 hours for a parka. . The company has a monthly contract with a supplier to procure 4,000 feet of required fabric. . The amount of machine time allocated to producing two products is 650 hours/month . Each month several skilled tailors are assigned for the production of these products for around 900 hours.
In order to conduct the sensitivity analysis, you will need to
download the lpSolveAPI package unless you have it already
installed in your R environment and make it available to this
notebook.
# Require will load the package only if not installed
# Dependencies = TRUE makes sure that dependencies are install
if(!require("lpSolveAPI",quietly = TRUE))
install.packages("lpSolveAPI",dependencies = TRUE, repos = "https://cloud.r-project.org")
library(lpSolveAPI)
You can use the following empty chunk to define your lp model
# Define your lp model
lpmark = make.lp(0, 2)
Use the fallowing chunk to define the type of optimization, set the objective function, and add the constraints to your model object.
# Define type of optimization
dump = lp.control(lpmark, sense="max")
# Set the objective function
set.objfn(lpmark, c(9, 12.5))
# add constraints
add.constraint(lpmark, c(8.5, 12.5), "<=", 4000) #Fabric constraint
add.constraint(lpmark, c(1.5, 2), "<=", 650) #machine time constraint
add.constraint(lpmark, c(2, 3), "<=", 900) #tailor hours constraint
add.constraint(lpmark, c(1, 0), "<=", 400) #maximum jackets
add.constraint(lpmark, c(0, 1), "<=", 150) #maximum parkas
Finally we can explore and solve the model using the lpSolveAPI package.
# View the problem formulation in tabular/matrix form
lpmark
## Model name:
## C1 C2
## Maximize 9 12.5
## R1 8.5 12.5 <= 4000
## R2 1.5 2 <= 650
## R3 2 3 <= 900
## R4 1 0 <= 400
## R5 0 1 <= 150
## Kind Std Std
## Type Real Real
## Upper Inf Inf
## Lower 0 0
Use the fallowing chunks to solve the optimization problem and display the optimum results.
# Solve
solve(lpmark)
## [1] 0
# Display the objective function optimum value
get.objective(lpmark)
## [1] 3950
# Display the decision variables optimum values
get.variables(lpmark)
## [1] 300 100
Use the following chunk to get the sensitivity results for the coefficients of the objective function.
# display sensitivity to coefficients of objective function.
get.sensitivity.obj(lpmark)
## $objfrom
## [1] 8.333333 12.000000
##
## $objtill
## [1] 9.375 13.500
Answer: The coefficient sensitivity results provide a range of values for the objective function coefficients (profits per unit for jackets and parkas) within which the current optimal solution remains unchanged.For the jacket’s profit per unit, the range is between approximately $8.33 and $9.38. For the parka’s profit per unit, the range is between approximately $12 and $13.50. Within these ranges, if the profits per unit for jackets and parkas remain within the specified bounds, the current optimal production quantities for jackets and parkas will not change. This means that as long as the profits per unit fall within these respective ranges, the recommended quantities of jackets and parkas for maximum profit will stay the same.
Use the following chunk to display the constraint sensitivity results
# display sensitivity to right hand side constraints.
get.sensitivity.rhs(lpmark)
## $duals
## [1] 0.0 4.0 1.5 0.0 0.0 0.0 0.0
##
## $dualsfrom
## [1] -1.000e+30 6.375e+02 8.750e+02 -1.000e+30 -1.000e+30 -1.000e+30 -1.000e+30
##
## $dualstill
## [1] 1.000000e+30 6.666667e+02 9.166667e+02 1.000000e+30 1.000000e+30
## [6] 1.000000e+30 1.000000e+30
Answer: The two non-zero sensitivity results in the context of the problem represent the impact of changes in the right-hand side (RHS) values of the constraints on the objective function (profit) while maintaining the current optimal solution. The non-zero sensitivity values imply that these constraints are binding, meaning they directly affect the optimal solution. In contrast, constraints with zero sensitivity (like the first constraint above) are non-binding and do not affect the optimal solution. Surplus/Slack: These sensitivity results indicate the surplus or slack in the constraints. The non-zero sensitivity values imply that there is room to relax these constraints by the specified amounts without affecting the optimality of the current solution. Marginal Values: The sensitivity values (dual values) indicate the marginal impact of relaxing or tightening the constraints. Larger sensitivity values suggest a higher impact on the objective function with changes in the constraint values.
Answer: The non-zero sensitivity result for the amount of fabric indicates that the company can decrease the amount of fabric available by up to approximately 637.5 units (feet) without affecting the optimal production plan for jackets and parkas or the overall profit. This surplus in fabric suggests that they currently have more fabric available than needed to maintain the current production levels.
Answer: The non-zero sensitivity result for machine time indicates that the company can decrease the allocated machine time without impacting the optimal production plan or the overall profit. The surplus in machine time suggests that the current allocation is more than required to meet the production demands for jackets and parkas at the current levels.
For this task we will be running a Monte Carlo simulation to calculate the probability that the daily return from S&P will be > 5%. From the historic data we are given that the S&P daily return follows a normal distribution with an average daily return of 0.03 (%) and a standard deviation of 0.97 (%).
First generate 100 random samples from the normal distribution. For the generated samples calculate the mean, standard deviation, and probability of occurrence where the simulation result is greater than 5%. (0.25 points)
# define the number of simulations/samples
runs = 100
# Use the defined normal distribution with given mean and standard deviation to create simulations
sims = rnorm(runs,mean=0.03,sd=0.97)
# Calculate the mean from the random distribution of samples
average = mean(sims)
average
## [1] -0.05365042
# Calculate the standard deviation from the random distribution of samples
std = sd(sims)
std
## [1] 0.9830862
# Calculate the probability of occurrence
prob = sum(sims >=0.05)/runs
prob
## [1] 0.45
# Repeat calculations here
# number of simulations/samples
runs1 = 1000
# random number generator per defined normal distribution with given mean and standard deviation
sims1 = rnorm(runs1,mean=0.03,sd=0.97)
# Calculate the mean and the standard deviation from the random distribution of samples
average1 = mean(sims1)
average1
## [1] 0.04295841
#the standard deviation
std1 = sd(sims1)
std1
## [1] 0.9489171
# Calculate the probability of occurrence
prob1 = sum(sims1 >=0.05)/runs1
prob1
## [1] 0.496
# Repeat calculations here
# number of simulations/samples
runs2 = 100000
# random number generator per defined normal distribution with given mean and standard deviation
sims2 = rnorm(runs2,mean=0.03,sd=0.97)
# Calculate the mean and the standard deviation from the random distribution of samples
average2 = mean(sims2)
average2
## [1] 0.03155758
#the standard deviation
std2 = sd(sims2)
std2
## [1] 0.9709964
# Calculate the probability of occurrence
prob2 = sum(sims2 >=0.05)/runs2
prob2
## [1] 0.49125
# Display your results in a tabular format
myresults <- data.frame (Runs = c("100", "1000", "10000"), Average = c(average, average1, average2), STD = c(std, std1, std2), Probability = c(prob, prob1, prob2))
myresults
## Runs Average STD Probability
## 1 100 -0.05365042 0.9830862 0.45000
## 2 1000 0.04295841 0.9489171 0.49600
## 3 10000 0.03155758 0.9709964 0.49125