OPTIMASI
UTS OPTIMASI
Kontak | : \(\downarrow\) |
naufal3433@gmail.com | |
https://www.instagram.com/m_naufalardiansyah/ | |
RPubs | https://rpubs.com/muhammad_naufal/ |
SOAL 1
Find the maximum solution to \(Z=4x+3y\)
Suppose that the objective function is subject to the following constraints:
\[ \begin{align} x≥0 \\ y≥2 \\ 2y≤25-x \\ 4y≤2x-8 \\ y≤2x-5 \\ \end{align} \]
Solve these problems using mathematical model and R packages (please explain it step-by-step).
## (0.0, 25.0)
## (0.0, 11.0)
\[ \begin{align*} &Line \space 1 & & Line \space 2& \\ 4y & \leq 2x-8 & y & \geq 2 \\ 2y & \leq 25-x & y & \geq 2 \\ 2y & \leq 25-x & 4y & \leq 2x-8 \\ \end{align*} \]
PERHITUNGAN Z
\[ Z = 4x + 3y\]
1)
\[ \begin{align*} 4y & \leq 2x-8 \space and \space y \geq 2 \\ {x-4 \over 2} & = 2 \\ 4 &= x-4 \\ x &= 8 \\ y &= 2 \\ Z & =(4\times 8)+ (3\times 2)=38 \end{align*} \]
2)
\[ \begin{align*} 4y & \leq 2x-8 \space and \space 2y \leq 25-x \\ {x-4 \over 2} & = {25-x \over 2} \\ 2x-8 &= 50-2x \\ 4x & = 58 \\ x &= 14.5 \\ y &= 5.25 \\ Z & =(4\times 14.5)+ (3\times 5.25)=73.75 \end{align*} \]
3)
\[ \begin{align*} 2y & \leq 25-x \space and \space y \geq 2 \\ {25-x \over 2} & = 2 \\ 25-x &= 4 \\ x &= 21 \\ y &= 2 \\ Z & =(4\times 21)+ (3\times 2)=90 \end{align*} \]
Maka dari 3 hasil di atas yang menghasilkan nilai maximum adalah \(2y \leq 25-x \space and \space y \geq 2\) dan menghasilkan nilai \(90\).
Untuk perhitungan R adalah sebagai berikut :
library(lpSolve)
<- c(4,3)
maxim <- matrix(c(1,2,
LHS -2,4,
-2,1,
0,1)
ncol=2, byrow=TRUE)
,<- c("<=","<=","<=",">=")
arah_kendala <- c(25,-8,-5,2)
RHS
# Penyelesaian
<- lp ("max",
model
maxim,
LHS,
arah_kendala,
RHS,compute.sens = TRUE)
print(model)
## Success: the objective function is 90
$solution model
## [1] 21 2
SOAL 2
Let say you are working as consultant for a boutique car manufacturer, producing luxury cars. They run on one-month (30 days) cycles, we have one cycle to show we can provide value. There is one robot, 2 engineers and one detailer in the factory. The detailer has some holiday off, so only has 21 days available.
The 2 cars need different time with each resource:
Resource time | Car A | Car B |
---|---|---|
Robot | 3 days | 4 days |
Engineer | 5 days | 6 days |
Detailer | 1.5 days | 3 days |
Car A provides $30,000 profit, whilst Car B offers $45,000 profit. At the moment, they produce 4 of each car per month, for $300,000 profit. Not bad at all, but we think we can do better for them.
## (0.0, 25.0)
## (0.0, 11.0)
Untuk perhitungan Rnya adalah sebagai berikut :
library(lpSolve)
<- c(30000,45000)
maxim_1 <- matrix(c(3,4,
LHS 5,6,
1.5,3)
ncol=2, byrow=TRUE)
,<- c("<=","<=","<=")
arah_kendala <- c(30,60,21)
RHS
# Penyelesaian
<- lp ("max",
model
maxim_1,
LHS,
arah_kendala,
RHS,compute.sens = TRUE)
print(model)
## Success: the objective function is 330000
$solution model
## [1] 2 6
library(gMOIP)
<- plotPolytope(
p1
LHS,
RHS,
maxim_1,type = rep("c", ncol(LHS)),
crit = "max",
faces = rep("c", ncol(LHS)),
plotFaces = TRUE,
plotFeasible = TRUE,
plotOptimum = FALSE,
labels = NULL
+ ggplot2::ggtitle("Feasible region ")
) p1
SOAL 3
Let say you would like to make some sausages and you have the following ingredients available:
Ingredient | Cost ($/kg) | Availability (kg) |
---|---|---|
Chicken | 4.32 | 30 |
Wheat | 2.46 | 20 |
Starch | 1.86 | 17 |
Assume that you will make 2 types of sausage:
- Economy (>40% Chicken)
- Premium (>60% Chicken)
- One sausage is 50 grams (0.05 kg)
According to government regulations of Indonesia:
- The most starch you can use in your sausages is 25%.
- You have a contract with a butcher, and have already purchased 23 kg Chicken, that must go in your sausages.
- You have a demand for 350 economy sausages and 500 premium sausages.
So, please figure out how to optimize the cost effectively to blend your sausages.
import pulp
= pulp.LpProblem("Cost minimising blending problem", pulp.LpMinimize) model
## C:\Users\DELLA\AppData\Roaming\Python\Python39\site-packages\pulp\pulp.py:1352: UserWarning: Spaces are not permitted in the name. Converted to '_'
## warnings.warn("Spaces are not permitted in the name. Converted to '_'")
= ['economy', 'premium']
sausage_types = ['chicken','wheat','starch']
ingredients
= pulp.LpVariable.dicts("weight kg",
ing_weight for i in sausage_types for j in ingredients),
((i, j) =0,
lowBound='Continuous') cat
# Objective Function
+= (
model
pulp.lpSum([4.32 * ing_weight[(i, 'chicken')]
+ 2.46 * ing_weight[(i, 'wheat')]
+ 1.86 * ing_weight[(i, 'starch')]
for i in sausage_types])
)
# Constraints
# 350 economy and 500 premium sausages at 0.05 kg
+= pulp.lpSum([ing_weight['economy', j] for j in ingredients]) == 350 * 0.05
model += pulp.lpSum([ing_weight['premium', j] for j in ingredients]) == 500 * 0.05
model
# Economy has >= 40% chicken, premium >= 60% chicken
+= ing_weight['economy', 'chicken'] >= (
model 0.4 * pulp.lpSum([ing_weight['economy', j] for j in ingredients]))
+= ing_weight['premium', 'chicken'] >= (
model 0.6 * pulp.lpSum([ing_weight['premium', j] for j in ingredients]))
# Sausages must be <= 25% starch
+= ing_weight['economy', 'starch'] <= (
model 0.25 * pulp.lpSum([ing_weight['economy', j] for j in ingredients]))
+= ing_weight['premium', 'starch'] <= (
model 0.25 * pulp.lpSum([ing_weight['premium', j] for j in ingredients]))
# We have at most 30 kg of chicken, 20 kg of wheat and 17 kg of starch available
+= pulp.lpSum([ing_weight[i, 'chicken'] for i in sausage_types]) <= 30
model += pulp.lpSum([ing_weight[i, 'wheat'] for i in sausage_types]) <= 20
model += pulp.lpSum([ing_weight[i, 'starch'] for i in sausage_types]) <= 17
model
# We have at least 23 kg of chicken to use up
+= pulp.lpSum([ing_weight[i, 'chicken'] for i in sausage_types]) >= 23 model
# Solve our problem
model.solve()
## 1
pulp.LpStatus[model.status]
## 'Optimal'
for var in ing_weight:
= ing_weight[var].varValue
var_value print ("The weight of {0} in {1} sausages is {2} kg".format(var[1], var[0], var_value))
## The weight of chicken in economy sausages is 7.0 kg
## The weight of wheat in economy sausages is 6.125 kg
## The weight of starch in economy sausages is 4.375 kg
## The weight of chicken in premium sausages is 16.0 kg
## The weight of wheat in premium sausages is 2.75 kg
## The weight of starch in premium sausages is 6.25 kg
= pulp.value(model.objective)
total_cost
print ("The total cost is €{} for 350 economy sausages and 500 premium sausages".format(round(total_cost, 2)))
## The total cost is €140.96 for 350 economy sausages and 500 premium sausages
SOAL 4
Please visualize a contour plot of the following function:
\[f(x,y)=x^2+y^2+3xy\]
How Coordinate Descent Works
<- function(x, y) {
f ^2 + y^2 + 3* x * y
x
}<- 30
n <- seq(-1.5, 1.5, len = n)
xpts <- seq(-1.5, 1.5, len = n)
ypts <- expand.grid(x = xpts, y = ypts)
gr <- with(gr, matrix(f(x, y), nrow = n, ncol = n))
feval par(mar = c(5, 4, 1, 1))
contour(xpts, ypts, feval, nlevels = 20, xlab = "x", ylab = "y")
points(-1, -1, pch = 19, cex = 2)
abline(h = -1)
How Steepest Descent Works
import numpy as np
import numpy.linalg as la
import scipy.optimize as sopt
import matplotlib.pyplot as pt
from mpl_toolkits.mplot3d import axes3d
def f(x):
return x[0]**2 + x[1]**2 + 3* x[0] * x[1]
def df(x):
return np.array([2*x[0]+3*x[1], 3*x[0]+2*x[1]])
= pt.figure()
fig = fig.gca(projection="3d") ax
## <string>:1: MatplotlibDeprecationWarning: Calling gca() with keyword arguments was deprecated in Matplotlib 3.4. Starting two minor releases later, gca() will take no keyword arguments. The gca() function should only be used to get the current axes, or if no axes exist, create new axes with default keyword arguments. To create a new axes with non-default arguments, use plt.axes() or plt.subplot().
= np.mgrid[-2:2:50j,-2:2:50j]
xmesh, ymesh = f(np.array([xmesh, ymesh]))
fmesh ax.plot_surface(xmesh, ymesh, fmesh)
How Newton Method Works
import numpy as np
import matplotlib.pyplot as plt
def Newton_Raphson_Optimize(Grad, Hess, x,y, epsilon=0.000001, nMax = 200):
#Initialization
= 0
i = np.empty(0),np.empty(0), np.empty(0)
iter_x, iter_y, iter_count = 10
error = np.array([x,y])
X
#Looping as long as error is greater than epsilon
while np.linalg.norm(error) > epsilon and i < nMax:
+=1
i = np.append(iter_x,x)
iter_x = np.append(iter_y,y)
iter_y = np.append(iter_count ,i)
iter_count print(X)
= X
X_prev = X - np.linalg.inv(Hess(x,y)) @ Grad(x,y)
X = X - X_prev
error = X[0], X[1]
x,y
return X, iter_x,iter_y, iter_count
def f_2(x,y):
return x**2 + y**2 + 3*x*y
def Grad_f_2(x,y):
= 2*x+3*y
g1 = 3*x+2*y
g2 return np.array([g1,g2])
def Hessian_f_2(x,y):
return np.array([[.02,0],[0,-.2]])
= Newton_Raphson_Optimize(Grad_f_2,Hessian_f_2,-2,-.01, nMax = 25) root_nr,iter_x_nr,iter_y_nr, iter_count_nr
## [-2. -0.01]
## [199.5 -30.11]
## [-15234. 2661.29]
## [1108972.5 -199235.81]
## [-79902906. 14442993.59]
## [ 5.74393866e+09 -1.03967066e+09]
## [-4.12699328e+11 7.47227026e+10]
## [ 2.96488281e+13 -5.36854019e+12]
## [-2.12995295e+15 3.85678479e+14]
## [ 1.5301357e+17 -2.7706831e+16]
## [-1.09923188e+19 1.99042841e+18]
## [ 7.8967530e+20 -1.4299007e+20]
## [-5.67293443e+22 1.02722387e+22]
## [ 4.07536927e+24 -7.37945538e+23]
## [-2.92769727e+26 5.30131382e+25]
## [ 2.10322323e+28 -3.80840139e+27]
## [-1.51093079e+30 2.73591069e+29]
## [ 1.08543488e+32 -1.96544600e+31]
## [-7.79763626e+33 1.41195325e+33]
## [ 5.60173002e+35 -1.01433058e+35]
## [-4.02421685e+37 7.28683139e+36]
## [ 2.89094997e+39 -5.23477382e+38]
## [-2.07682440e+41 3.76059984e+40]
## [ 1.49196618e+43 -2.70157061e+42]
## [-1.07181092e+45 1.94077650e+44]
= np.linspace(-3,3,100)
x = np.linspace(-1,1,100)
y = np.meshgrid(x, y)
X, Y = f_2(X, Y)
Z
#Angles needed for quiver plot
= iter_x_nr[1:] - iter_x_nr[:-1]
anglesx_nr = iter_y_nr[1:] - iter_y_nr[:-1]
anglesy_nr
= plt.figure(figsize = (16,8))
fig
#Surface plot
= fig.add_subplot(1, 2, 1, projection='3d')
ax = 5, cstride = 5, cmap = 'jet', alpha = .4, edgecolor = 'none' )
ax.plot_surface(X,Y,Z,rstride = 'darkblue', marker = 'o', alpha = .4, label = 'Newton')
ax.plot(iter_x_nr,iter_y_nr, f_2(iter_x_nr,iter_y_nr),color
ax.legend()
#Rotate the initialization to help viewing the graph
#ax.view_init(45, 280)
'x')
ax.set_xlabel('y')
ax.set_ylabel(
#Contour plot
= fig.add_subplot(1, 2, 2)
ax 60, cmap = 'jet')
ax.contour(X,Y,Z, #Plotting the iterations and intermediate values
## <matplotlib.contour.QuadContourSet object at 0x000000003F59B7C0>
= 'darkblue', marker = 'o', label = 'Newton')
ax.scatter(iter_x_nr,iter_y_nr,color -1], iter_y_nr[:-1], anglesx_nr, anglesy_nr, scale_units = 'xy', angles = 'xy', scale = 1, color = 'darkblue', alpha = .3)
ax.quiver(iter_x_nr[:
ax.legend()
'Newton Method')
ax.set_title(
plt.show()
How Conjugate Gradient Works
import numpy as np
import matplotlib.pyplot as plt
import math
from math import *
def f(x1, x2):
return x1**2 + x2**22 + 3* x1 * x2
def gradient(x1, x2):
return np.array([2*x1+3*x2, 3*x1+2*x2])
def norm(matrice_1x2):
= matrice_1x2.shape[0]
n_line = 0
N for i in range(n_line):
+= matrice_1x2[i]**2
N return math.sqrt(N)
= 50,50
x1, x2 = 0.1
t = pow(10,-6)
epsilon = gradient(x1, x2)
grad_f = norm(grad_f)
n_grad = 1
i = [[x1, x2]]
evolution_X1_X2
while n_grad > epsilon:
= -grad_f
direction = x1 + t*direction[0], x2 + t*direction[1]
x1, x2 = np.vstack((evolution_X1_X2, [x1, x2]))
evolution_X1_X2 = gradient(x1, x2)
grad_f = norm(grad_f)
n_grad +=1
i
= evolution_X1_X2[:, 0]
evolution_X1 = evolution_X1_X2[:, 1] evolution_X2
= np.linspace(2, 3.5, 150)
x1 = np.linspace(0.25, 1.75, 150)
x2 = np.meshgrid(x1, x2)
X1, X2 = f(X1, X2)
Z = plt.figure(figsize = (10,7))
fig = plt.contour(X1, X2, Z, 20)
contours = True, fontsize = 10)
plt.clabel(contours, inline "Evolution of the cost function during gradient descent with level circles", fontsize=15)
plt.title(
plt.plot(evolution_X1, evolution_X2)'*', label = "Cost function")
plt.plot(evolution_X1, evolution_X2, 'x1', fontsize=11)
plt.xlabel('x2', fontsize=11)
plt.ylabel( plt.colorbar()
## <matplotlib.colorbar.Colorbar object at 0x000000003F6F8520>
= "upper right")
plt.legend(loc plt.show()
# Referensi