<jupyter_start><jupyter_text>Q3Mercotic is a leader in slip-ring industry. A $750,000 order has just been received. Unfortunately, Mercotic does not have enough wiring and harnessing capacity to fill the order by its due date. However, the company can subcontract any portion of this order to one of its competitors. Mercotic wants to determine the number of slip rings to make and number to buy to fill the customer order at the least possible cost. All the necessary information is given in the table below. The wiring and harnessing capacities are 11,000 and 4,500 hours, respectively.(a) How much of each model should Mercotic buy and make to minimize costs?(b)	Suppose now that Mary, Mercotic’s CEO would like to make sure that the firm produces at least as many Model 2s as Model 3s. She believes that this will decrease costs. Do you agree with this claim?(c)	Mary consults industrial and manufacturing engineers, and they suggest that with a new process, each model can be produced using half of their current harnessing requirements. If this new process costs $10,000, should Mercotic use it?   (Assume that Marc doesn’t require at least as many Model 2s and Model 3s.)(d)	Mary suspects that only the relative costs of making and buying rather than the exact costs matter in the optimal solution. Specifically, she thinks that if the costs of making and buying increases by the same percentage, the optimal plan stays the same. Is she correct?<jupyter_code>#Q3(a)

# M1 = Number of model 1 slip rings to make in-house
# M2 = Number of model 2 slip rings to make in-house
# M3 = Number of model 3 slip rings to make in-house
# B1 = Number of model 1 slip rings to buy from competitor
# B2 = Number of model 2 slip rings to buy from competitor
# B3 = Number of model 3 slip rings to buy from competitor

from scipy.optimize import linprog 
# Now linprog() has been imported, optimizing can be started
obj1 = [50, 83, 130, 61, 97, 145] # obj holds the coefficients from the objective function.
 #      ─┬  ─┬   ─┬  ─┬  ─┬   ─┬
 #       │   │    │   │   │    │
 #       │   │    │   │   │    └┤ Coefficient for B3
 #       │   │    │   │   └┤ Coefficient for B2
 #       │   │    │    └┤Coefficient for B1
 #       │   │    └┤ Coefficient for M3
 #       │   └┤ Coefficient for M2
 #       └┤ Coefficient for M1

lhs_eq1 = [[1,0,0,1,0,0],  # Number oder of Model 1 constraint left side
          [0,1,0,0,1,0],  # Number oder of Model 2 constraint left side
          [0,0,1,0,0,1]]  # Number oder of Model 3 constraint left side
#lhs_eq holds the left-side coefficients from the equality (Number oder of Model 1&2&3 constraint) constraint.

rhs_eq1 = [3000,  # Number oder of Model 1 constraint right side
          2000,  # Number oder of Model 2 constraint right side
          900]   # Number oder of Model 3 constraint right side
#rhs_eq holds the right-side coefficients from the equality (Number oder of Model 1&2&3 constraint) constraint.

lhs_ineq1 = [[2,1.5,3,0,0,0], # Wiring capacities constraint left side
            [1,2,1,0,0,0]]  # Harnessing capacities constraint left side
#lhs_ineq holds the left-side coefficients from the inequality (Wiring and Harnessing) constraints.

rhs_ineq1 = [11000 ,  # Wiring capacities constraint right side
            4500],  # Harnessing capacities constraint right side
#rhs_ineq holds the right-side coefficients from the inequality (Wiring and Harnessing) constraints.

bnd1 = [(0, float("inf")),  # Bounds of M1
       (0, float("inf")),  # Bounds of M2
       (0, float("inf")),  # Bounds of M3
       (0, float("inf")),  # Bounds of B1
       (0, float("inf")),  # Bounds of B2
       (0, float("inf"))]  # Bounds of B3
# bnd defines the bounds for each variable in the same order as the coefficients. They are all between zero and positive infinity.

opt1 = linprog(c=obj1, A_ub=lhs_ineq1, b_ub=rhs_ineq1,   #lingrog() optimizes and solves the problem
                A_eq=lhs_eq1, b_eq=rhs_eq1,
                 bounds=bnd1,
               method="revised simplex")

opt1 # Here we can see the firm should make 3,000, 300, and 900 models 1,2, and 3s, respectively, and purchase 1700 Model 2s. The optimal cost is $456,800.
#Q3(b)

obj2 = [50, 83, 130, 61, 97, 145]
lhs_eq2 = [[1,0,0,1,0,0], 
          [0,1,0,0,1,0],  
          [0,0,1,0,0,1]] 
rhs_eq2 = [3000,  
          2000,  
          900]
lhs_ineq2 = [[2,1.5,3,0,0,0],
            [1,2,1,0,0,0],
            [0,-1,1,0,0,0]] # We add a constraint in the solver where M2>=M3, which is -M2+M3<=0
rhs_ineq2 = [11000 ,  
            4500,
            0], 

bnd2 = [(0, float("inf")),  
       (0, float("inf")),  
       (0, float("inf")),  
       (0, float("inf")),  
       (0, float("inf")),  
       (0, float("inf"))]
opt2 = linprog(c=obj2, A_ub=lhs_ineq2, b_ub=rhs_ineq2,   #lingrog() optimizes and solves the problem
                A_eq=lhs_eq2, b_eq=rhs_eq2,
                 bounds=bnd2,
               method="revised simplex")

opt2

diff = opt1.fun - opt2.fun
if diff > 0 :
    print("I do agree with Mary's claim, that is, this additional constraint decrease costs by",opt1.fun,"-", opt2.fun,"=", abs(diff))
else:
    print("I don't agree with Mary's claim. Instead, this additional constraint increase costs by",opt2.fun,"-", opt1.fun,"=", abs(diff))
#Q3(c)
obj3 = [50, 83, 130, 61, 97, 145]
lhs_eq3 = [[1,0,0,1,0,0], 
          [0,1,0,0,1,0],  
          [0,0,1,0,0,1]] 
rhs_eq3 = [3000,  
          2000,  
          900]
lhs_ineq3 = [[2,1.5,3,0,0,0],
            [0.5,1,0.5,0,0,0]] #Here each model can be produced using half of their current harnessing requirements.
rhs_ineq3 = [11000 ,  
            4500] 

bnd3 = [(0, float("inf")),  
       (0, float("inf")),  
       (0, float("inf")),  
       (0, float("inf")),  
       (0, float("inf")),  
       (0, float("inf"))]
opt3 = linprog(c=obj3, A_ub=lhs_ineq3, b_ub=rhs_ineq3,   #lingrog() optimizes and solves the problem
                A_eq=lhs_eq3, b_eq=rhs_eq3,
                 bounds=bnd3,
               method="revised simplex")

opt3
diff1 = opt1.fun - opt3.fun
if diff1 > 0 :
    print("The total cost decreases from", opt1.fun, "to", opt3.fun,", which is a decrease of", diff1)
    if diff1 > 10000:
        print("Since this decrease is greater than $10,000, the firm should use this new process.")
    else:
        print("Don't use this process.")
else:
    print("Don't use this process.")
#Q3(d)
#Let the costs of making and buying increases by the same 10% 
obj4 = [50*1.1, 83*1.1, 130*1.1, 61*1.1, 97*1.1, 145*1.1] #each cost should multiplied by 1.1
lhs_eq4 = [[1,0,0,1,0,0], 
          [0,1,0,0,1,0],  
          [0,0,1,0,0,1]] 
rhs_eq4 = [3000,  
          2000,  
          900]
lhs_ineq4 = [[2,1.5,3,0,0,0],
            [1,2,1,0,0,0]] #Here each model can be produced using half of their current harnessing requirements.
rhs_ineq4 = [11000 ,  
            4500] 

bnd4 = [(0, float("inf")),  
       (0, float("inf")),  
       (0, float("inf")),  
       (0, float("inf")),  
       (0, float("inf")),  
       (0, float("inf"))]
opt4 = linprog(c=obj4, A_ub=lhs_ineq4, b_ub=rhs_ineq4,   #lingrog() optimizes and solves the problem
                A_eq=lhs_eq4, b_eq=rhs_eq4,
                 bounds=bnd4,
               method="revised simplex")

opt4
if opt1.x.all() == opt4.x.all():
    print("The solution does not change. Mary is correct.")
else:
    print("Mary is wrong.")
################################################################################
#Q7
from pulp import LpMaximize, LpProblem, LpStatus, lpSum, LpVariable
# Create the model
model = LpProblem(name="Williams_Max_Revenue", sense=LpMaximize)

# Initialize the decision variables
x = LpVariable(name="PE", lowBound=0) # PE = Per unit price of the Executive, lowBound = 0 means now 0 <= PE <= infinity.
y = LpVariable(name="PC", lowBound=0) # PC = Per unit price of the Creativista, lowBound = 0 means now 0 <= PC <= infinity.

# Add the objective function to the model  MAX 1000 PE + 1500 PC
obj_func = 1000 * x + 1500 * y
model += obj_func

# Add the constraints to the model
model += (1000 - x >= 800 - y, "Executive_NU_constraint")  
#1000 - PE > 800 – PC (This constraint ensures that the net utility of the executive is higher for group 1) 

model += (1500 -y >= 1200 - x, "Creativista_NU_constraint")
#1500 – PC > 1200 – PE (This constraint ensures that the net utility of the creativista is higher for group 2) 


model += (1000 - x >= 0, "Executivew_value_constraint")
#1000 – PE >= 0
model += (1500 - y >= 0, "Creativista_value_constraint")
#1500 – PC >= 0 


model
# Solve the problem
status = model.solve()
#.solve() calls the underlying solver, modifies the model object, and returns the integer status of the solution, which will be 1 if the optimum is found. 

print(f"status: {model.status}, {LpStatus[model.status]}") # This model.status returns the integer status of the solution, which will be 1 if the optimum is found. 
print(f"The optimal revenue is $ {model.objective.value()}") # model.objective holds the value of the objective function, which is 2,950,000
for var in model.variables():   
    print(f"{var.name}: {var.value()}")
# The objects PE and PC have the optimal values of the decision variables. model.variables() returns a list with the decision variables:
print("The firm should set the price of the Executive as $", model.variables()[1].value())
print("The firm should set the price of the Creativista as $", model.variables()[0].value())
for name, constraint in model.constraints.items():    # model.constraints contains the values of the slack variables
    print(f"{name}: {constraint.value()}")<jupyter_output>Executive_NU_constraint: 500.0
Creativista_NU_constraint: 0.0
Executivew_value_constraint: 0.0
Creativista_value_constraint: 200.0
{'fraction_non_alphanumeric': 0.12444990277351346, 'fraction_numerical': 0.05987104697574455, 'mean_word_length': 3.1336717428087986, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '265823', 'license': 'MIT', 'n_tokens_mistral': 3519, 'n_tokens_neox': 3235, 'n_words': 1212, 'path': 'Solution Code/ICE 2 Q3.ipynb', 'repo_name': 'ReynaYC/Business_Analysis_Linear_Programing', 'size': '9771'}