Jon Duan

  1. A turkey producer wants to feed her turkeys the minimum daily requirement of nutrients A, B and C at lowest costs. Daily requirements are 28 units of A, 20 of B and 12 of C. Feed grain X contains 1A, 1B and 1C, while feed grain Y contains 2A, 1B and 紺. The price of X = $1.25 and the price of Y = $2.00. The problem is to find the least-cost combination of X and Y that fulfills the minimum nutrient requirements.

(a) Provide an analytical representation of the mathematical programming problem.

(i) The primal problem in its ‘original’ form

\[\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.

(ii) The primal problem in ‘standard’ form (a standard maximum problem)

\[\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} \]

[PDF]Converting a linear program to standard form - MIT

(iii)The dual representation of the problem

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} \]

(b) Provide a graphical solution of the original problem. Graphically show what happens if the price of X rises from $1.25 to $1.80? What happens if it rises to $2.00?

graphical solution of the original problem

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.

(c) Solve the problem in GAMS, providing the original GAMS input file (not the code from the list file), output from GAMS in the form of the value of the objective function, the output levels, marginal values, and shadow prices. In this case, use the display function to write the desired output to the list file.

GAMS code

*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;

The table

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

(d) Now solve the problem as follows: Write a program in R or Matlab that creates the data (or calls the data from a .csv file), then calls GAMS to solve the problem and ‘dump’ the GAMS output into a .csv file using GAMS ‘put’ command (you will thus need to modify the GAMS program in part c), and retrieves the GAMS output into R/Matlab.

For price vector

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")

For requirement of nutrient vector

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")

For nutrienttable

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") 

System call GAMS from R

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"))