Jon Duan
\[\begin{aligned} \min_{x,y} \quad TC & = 1.25x+2y \\ s.t. \quad 1x + 2 y & \ge 28 \\ 1x + 1 y & \ge 20 \\ 1x +0.5y & \ge 12 \\ x & \ge 0 \\ y & \ge 0 \end{aligned} \]
Where \(TC\) is the total cost of the grain used to feed turkey.
\[\begin{aligned} \max_{x,y} \quad -Z & = -1.25x-2y \\ s.t. \quad 1x + 2 y - s1 & = 28 \\ 1x+1y -s2 & = 20 \\ 1x+0.5y - s3 & = 12 \\ x & \ge 0 \\ y & \ge 0 \end{aligned} \]
Since the primal problem is the minimization of the cost, the dual representation will be the maximization of nutrient supply. The decision variable in primal is the grain X and Y. In the dual, the DUAL variables have an important interpretation as shadow prices.
S
is called a surplus variable
, which measures the amount by which the LHS exceeds the RHS. - To convert a “\(\ge\)” constraint to an equality, add a surplus variable.
I choose \(z\) as the decision variable for dual. \(z_i\) are the shadow price of the nutrient A, B, and C.
The dual representation of the original problem
\[\begin{aligned} \max_{z_1,z_2,z_3} \quad & = 28z_1 +20z_2 + 12z_3 \\ s.t. \quad 1z_1 + 1z_2 + 1z_3 & \le 1.25 \\ 2z_1 + 1z_2 + 0.5z_3 & \le 2 \\ z_1 & \ge 0 \\ z_2 & \ge 0 \\ z_3 & \ge 0 \end{aligned} \]
The graphical solution of the original problem are: > - minimum total cost: 31 > - X: 12 > - Y: 8
If the price of X rises to $1.80, the solution are: - minimum total cost: 37.6 - X: 12 - Y: 8
if the price of X rises to $2.00, the solution are: - minimum total cost: 40 - X: 4 - Y: 16
And the line between first optimal solution (12,8) red square dot and third optimal solution (4, 16) black square dot.
Tools from geogebra which provides online graphing service.
*ECON549 HW1
SETS j daily requirement of nutrients /A, B, C/
i grain grain /X, Y/;
PARAMETERS
*require(j) /A 28,
* B 20,
* C 12/
require(j) daily requirement of nutrients vector
price(i) price vector;
*price(i) /X 1.25,
* Y 2.00 /
$include requirevector.gms
$include pricevector.gms
*price('X')=1.5 ;price('Y')=2.00 ;
*TABLE nutrienttable(i,j) nutrient table
* A B C
*X 1 1 1
*Y 2 1 0.5
;
TABLE nutrienttable(i,j) nutrient table created in R file
$ifthen not exist A.csv
A B C
X 1 1 1
Y 2 1 0.5
$else
$ondelim
$include nutrienttable.csv
$offdelim
$endif
;
Variable
TC Value of objective function (total cost);
Positive variable grain(i) grain levels;
Equation
obj objective function
nutrient_equ(j) nutrient constraint meet requirement of nutrient
;
obj.. TC =e= sum(i, price(i)*grain(i));
nutrient_equ(j).. sum(i, grain(i)*nutrienttable(i, j) )
=g= require(j);
Model HW1 /all/;
Solve HW1 using LP minimizing TC;
Display TC.L, TC.M,grain.l, grain.m ;
*
* Write shadow prices
*
file HWresult /econ549hw.csv/; HWresult.pc=5 ;
put Hwresult;
put 'Level','Marginals' /;
loop (i, put i.tl, grain.L(i), grain.m(i) /);
put "TC" TC.l , TC.m/;
put "modelstat" HW1.modelstat /;
put "solvestat" HW1.solvestat /;
put '',"Levels", "Shadow prices" /;
loop(j, put j.tl, nutrient_equ.l(j), nutrient_equ.m(j) /);
putclose HWresult;
library("knitr")
#install.packages("xtable")
library("xtable")
setwd("H:/Dropbox/book/uvic_economics/549/tutorial/R/457")
gamsoutputtable <-read.csv("econ549hw.csv")
kable(gamsoutputtable)
Level | Marginals | |
---|---|---|
X | 12.00 | 0.00 |
Y | 8.00 | 0.00 |
TC | 31.00 | 0.00 |
modelstat | 1.00 | |
solvestat | 1.00 | |
Levels | Shadow prices | |
A | 28.00 | 0.75 |
B | 20.00 | 0.50 |
C | 16.00 | 0.00 |
From the equation, Marginal (.m) - dual variable, shadow price,
These data show the shadow price of A is 0.75
the shadow price of B is 0.50
the shadow price of C is 0
Write a price vector to gms file for GAMS.
pricevector<-c(1.25, 2.00)
names(pricevector)<-c("X","Y")
# Format the output for GAMS which needs we define or assign the value to price separately.
priceline <- paste("price('X') =", pricevector["X"], ";" ,
"price('Y') =", pricevector["Y"], ";")
#writeLines(priceline, "pricevector.gms")
#cat is easy to set up than writeLines
# write a file for GAMS
cat(priceline,file="pricevector.gms",sep="\n")
Write a requirement vector to gms file for GAMS.
requirevector<-c(28, 20, 12)
names(requirevector)<-c("A","B", "C")
requireline <- paste("require('A') =", requirevector["A"],";" ,
"require('B') =", requirevector["B"],";" ,
"require('C') =", requirevector["C"],";")
# write a file for GAMS
cat(requireline,file="requirevector.gms",sep="\n")
Write a nutrient table to gms file for GAMS.
nutrienttable<-matrix(c(1,1,1,2,1,0.5), nrow = 2,byrow = T)
nutrienttable<-setNames(data.frame(nutrienttable), c('A','B','C'))
row.names(nutrienttable)<-c("X","Y")
# write a file for GAMS
write.csv(nutrienttable ,"nutrienttable.csv")
Run GAMS and generate the optimal solution by linear programming.
#setwd("I:\\j\\jonduan\\COURSES\\549\\457")
# check the working directory
#getwd()
# check the files in the directory
#dir()
# Use a variable or not.
# Since there is a blank space in 'Program Files (x86)', cmd does not work.
#cmd= paste("C:\\Program Files (x86)\\GAMS\\win32\\24.2\\gamside.exe",
# "ECON549_HW1.gms", "lo=2")
#system(cmd)
#system(paste("C:\\GAMS\\win64\\gamside.exe", "ECON549_HW1.gms", "lo=2"),wait = T)
system(paste("F:\\GAMS\\win32\\23.9\\gamside.exe", "ECON549_HW1.gms", "lo=2"))
#read file from GAMS
result <- read.csv("econ549hw.csv")
library(xtable)
#xtable(result)
kable(result)
Level | Marginals | |
---|---|---|
X | 12.00 | 0.00 |
Y | 8.00 | 0.00 |
TC | 31.00 | 0.00 |
modelstat | 1.00 | |
solvestat | 1.00 | |
Levels | Shadow prices | |
A | 28.00 | 0.75 |
B | 20.00 | 0.50 |
C | 16.00 | 0.00 |
\[A = \begin{bmatrix} 2 & -1 & 0 \\ -1 & 2 & -1 \\ 0 & -1 & 2 \end{bmatrix}\implies \begin{bmatrix} -1 & 2 & -1 \\ 2 & -1 & 0\\ 0 & -1 & 2 \end{bmatrix} \\ \implies \begin{bmatrix} 1 & -2 & 1 \\ 2 & -1 & 0\\ 0 & -1 & 2 \end{bmatrix} \implies \begin{bmatrix} 1 & -2 & 1 \\ 0 & 3 & -2\\ 0 & -1 & 2 \end{bmatrix}\]