You are on page 1of 9

Homework 1: Linear programs

Problem: 1

1.1 a) Given the choice of the solvers Clp, ECOS, and SCS, which one would you choose? Why?

I will choose Clp because the problem is a linear optimation problem. Clp is designed support LP, so Clp solver
will be faster than other optimation solvers.

1.2 b) Solve the problem using your selected solver. Print the termination status to check whether you
have indeed obtained the optimal solution.

In [72]: using Pkg


Pkg.add("Clp")
using JuMP, Clp
m = Model(with_optimizer(Clp.Optimizer))

@variable(m, 0<= x1 <= 3)


@variable(m, 0<= x2 <= 3)
@variable(m, 0<= x3 <= 3)

@constraint(m, 2*x1<= x2 - x3 + 2)
@objective(m, Max, 6*x1 - 2*x2 + 3*x3)

optimize!(m)
println("termination status:")
println(termination_status(m))

Resolving package versions...


Updating `~/.julia/environments/v1.3/Project.toml`
[no changes]
Updating `~/.julia/environments/v1.3/Manifest.toml`
[no changes]
termination status:
OPTIMAL
Coin0506I Presolve 1 (0) rows, 3 (0) columns and 3 (0) elements
Clp0006I 0 Obj 0 Dual inf 8.9999998 (2)
Clp0006I 1 Obj 9
Clp0000I Optimal - objective value 9
Clp0032I Optimal objective 9 - 1 iterations time 0.002

1.3 c) What is the optimal objective value? What is the optimal solution for the variables x1 and x2?
In [38]: optimal_value = objective_value(m)
x2_value= value(x2)
x3_value= value(x3)
println("optimal objective value: ", optimal_value)
println("The optimal solution for the variables x2 is ", x2_value)
println("The optimal solution for the variables x3 is ", x3_value)

optimal objective value: 9.0


The optimal solution for the variables x2 is 3.0
The optimal solution for the variables x3 is 3.0

1.4 d) Can you change one of the problem parameters to make the problem infeasible? Solve the new
problem in JuMP and print the termination status to demonstrate that the problem is infeasible.

change constraint from 2x1 ≤ x2 − x3 + 2 to 2x1 ≤ x2 - x3 -9

In [51]: new_model = Model(with_optimizer(Clp.Optimizer))


@variable(new_model, 0 <= x1 <= 3)
@variable(new_model, 0 <= x2 <= 3)
@variable(new_model, 0 <= x3 <= 3)
@constraint(new_model, 2*x1<= x2 - x3 - 9)
@objective(new_model, Max, 6*x1 - 2*x2 + 3*x3)
optimize!(new_model)

println("Termination Status:",termination_status(new_model))

Termination Status:INFEASIBLE
Coin0507I Presolve determined that the problem was infeasible with tole
rance of 1e-08
Clp3003W Analysis indicates model infeasible or unbounded
Clp0006I 0 Obj 0 Primal inf 8.9999999 (1) Dual inf 8.9999998 (2)
Clp0006I 2 Obj -24 Primal inf 5.9999999 (1)
Clp0006I 2 Obj -24 Primal inf 5.9999999 (1)
Clp0001I Primal infeasible - objective value -24
Clp0032I PrimalInfeasible objective -24 - 2 iterations time 0.002

Problem: 2
2.1 a)

the decision variables are the given food item which he should take. they are 77 elements, we can represent
them as an array [x1 x2 ... x77]

The objective of this optimization problem is to minimize the total cost of food. x1+x2+...+x77

The constraints are: (1)The variables are all non-negative number: x>=0 (2)The nutrients absorbed must meeting
the recommended daily allowance (RDA) of several nutrient. If we denote variable as array x, and donote RDA
as array b: A^T x >=b

2.2 b)
In [73]: using Pkg
Pkg.add("CSV")
using CSV
using JuMP, Clp
df = CSV.read("stigler.csv")
## m:num rows, n:num columns
(m,n) = size(df)

n_nutrients = 2:n
n_foods = 2:m

nutrients = names(df)[n_nutrients] # the list of nutrients


foods = df[n_foods,1] # the list of foods

# Put the data of nutrients and foods into an array


data = convert(Matrix{Float64}, df[n_foods,n_nutrients])
# lower[i] is the minimum daily requirement of nutrient i
lower = convert(Vector{Float64}, df[1,n_nutrients])

nutrient_model = Model(with_optimizer(Clp.Optimizer))

@variable(nutrient_model, x[1:length(n_foods)] >= 0)


for i in 1:length(lower)
@constraint(nutrient_model, sum(x[j] * data[j,i] for j in 1:
length(n_foods)) >= lower[i])
end
@objective(nutrient_model, Min, sum(x[i] for i in 1:length(n_foods)))
optimize!(nutrient_model)

Resolving package versions...


Updating `~/.julia/environments/v1.3/Project.toml`
[no changes]
Updating `~/.julia/environments/v1.3/Manifest.toml`
[no changes]
Coin0506I Presolve 9 (0) rows, 76 (-1) columns and 569 (-1) elements
Clp0006I 0 Obj 0 Primal inf 5.1310537 (9)
Clp0006I 6 Obj 0.10866228
Clp0000I Optimal - objective value 0.10866228
Coin0511I After Postsolve, objective 0.10866228, infeasibilities - dual
0 (0), primal 0 (0)
Clp0032I Optimal objective 0.1086622782 - 6 iterations time 0.002, Pres
olve 0.00

2.3 c)

The cheapest diet is $39.66173154546625 per year. It's less than Stigler’s assumption. The foods in the diet are
Wheat Flour, Liver, Cabbage, Spinach, and Navy Beans.
In [53]: println(termination_status(nutrient_model))
min_cost = objective_value(nutrient_model)
println("The annual cost for optimal diet is ", 365*min_cost, " dollars"
)
println("The foods in the diet are:")
for i in 1:length(n_foods)
if value(x[i]) > 0
println(foods[i], ": ", value(x[i]))
end
end

OPTIMAL
The annual cost for optimal diet is 39.66173154546625 dollars
The foods in the diet are:
Wheat Flour (Enriched): 0.02951906167648827
Liver (Beef): 0.0018925572907052643
Cabbage: 0.011214435246144865
Spinach: 0.005007660466725203
Navy Beans, Dried: 0.061028563526693246

2.4 d)

In [74]: vegetarian_model=Model(with_optimizer(Clp.Optimizer))
@variable(vegetarian_model, x[1:length(n_foods)] >= 0)
for i in 1:length(lower)
@constraint(vegetarian_model, sum(x[j] * data[j,i]
for j in 1:length(n_foods))>= lower[i])
end
@constraint(vegetarian_model, x[59] .== 0)
@constraint(vegetarian_model, x[22:40] .== 0)
@constraint(vegetarian_model, x[19] .== 0)
@objective(vegetarian_model, Min, sum(x[i] for i in 1:length(n_foods)))
optimize!(vegetarian_model)

Coin0506I Presolve 9 (-21) rows, 56 (-21) columns and 427 (-164) elemen
ts
Clp0006I 0 Obj 0 Primal inf 5.4119206 (9)
Clp0006I 7 Obj 0.10903744
Clp0000I Optimal - objective value 0.10903744
Coin0511I After Postsolve, objective 0.10903744, infeasibilities - dual
0 (0), primal 0 (0)
Clp0032I Optimal objective 0.1090374366 - 7 iterations time 0.002, Pres
olve 0.00
In [50]: println(termination_status(vegetarian_model))
min_cost = objective_value(vegetarian_model)
println("The annual cost for optimal diet is ", 365*min_cost, " dollars"
)
println("The foods in the diet are:")

for i in 1:length(n_foods)
if value(x[i]) > 0
println(foods[i], ": ", value(x[i]))
end
end

OPTIMAL
The annual cost for optimal diet is 39.79866435040896 dollars
The foods in the diet are:
Wheat Flour (Enriched): 0.03545558140888768
Evaporated Milk (can): 0.008591461668763496
Cabbage: 0.011249517312443502
Spinach: 0.005112832613199648
Navy Beans, Dried: 0.04862804357316859

The vegetarian solution is more expensive than normal solution which is expected because more nurients can
be find from both meat and vegetables.

Problem 3 Polyhedron modeling

3.1 a)

⎡ 1 0 0 ⎤
⎢ ⎥
⎢ −1 0 0 ⎥
⎢ ⎥
0 1 0
𝐴 = ⎢ ⎥
⎢ 0 −1 0 ⎥
⎢ ⎥
0 0 1
⎢ ⎥
⎣ 0 0 −1 ⎦

⎡ 1⎤
⎢ ⎥
⎢ 1⎥
⎢ ⎥
1
𝑏 = ⎢ ⎥
⎢ 1⎥
⎢ ⎥
1
⎢ ⎥
⎣ 1⎦
3.2 b)
⎡ 1 1 1 ⎤
⎢ ⎥
⎢ 1 1 −1 ⎥

⎢ ⎥
1 −1 −1
⎢ ⎥
⎢ 1 −1 1 ⎥
𝐴 =
⎢ ⎥
−1 1 1
⎢ ⎥
⎢ −1 1 −1 ⎥
⎢ ⎥
−1 −1 −1
⎢ ⎥
⎣ −1 −1 1 ⎦

⎡ 1⎤
⎢ ⎥
⎢ 1⎥
⎢ 1⎥
⎢ ⎥
⎢ 1⎥
𝑏 =
⎢ ⎥
1
⎢ ⎥
⎢ 1⎥
⎢ ⎥
1
⎢ ⎥
⎣ 1⎦

Problem 4 Standard form with equality constraints.

4.1 a)
⎡ −1 6 −1 1 1 −1 0 0 0 0 ⎤
⎢ ⎥
⎢ 0 7 0 1 0 0 0 0 0 0 ⎥

⎢ ⎥
0 0 1 1 0 0 1 0 0 0
𝐴 = ⎢ ⎥
⎢ 0 1 0 0 0 0 0 1 0 0 ⎥
⎢ ⎥
0 0 1 0 0 0 0 0 1 0
⎢ ⎥
⎣ 0 0 0 1 0 0 0 1 0 1 ⎦

𝑇
𝑏 = [4 14 5 6 6 4]

𝑇
𝑐 = [3 −1 0 0 −3 0 0 0 0 ]

𝑇
𝑥 = [ 𝑛1 𝑛2 𝑛3 𝑛4 𝑠1 𝑠2 𝑠3 𝑠4 𝑠5 𝑠6 ]
I denote z1 = n1 - s1 the z1 is not restricted by sign, so it can be sign to the difference of two positive number.
And the subsitute all z1 by the difference.

then, n2 = z2 + 1 the z2 satisfy non-nagtive property. we subsitute all z2 with n2-1 for all z2 in the problem.

Then, do the same for z3 and z4. In order to dealing with the inequalities, bring the surplus variables s2, s3, s4,
s5, s6. For the larger inequality, I minus a non-negative number on the left and change "larger than" to "equal".
And, for the "smaller" add a non-nagative number on the left and change the "smaller than"to "equal". for both,
the property still hold for original variables on the left.

4.2 b)

In [75]: original_model = Model(with_optimizer(Clp.Optimizer))

@variable(original_model, z[i = 1:4])

@constraint(original_model, -1 <= z[2] <= 5)


@constraint(original_model, -1 <= z[3] <= 5)
@constraint(original_model, -2 <= z[4] <= 2)
@constraint(original_model, -z[1] + 6z[2] - z[3] + z[4]>= -3)
@constraint(original_model, 7z[2] + z[4] == 5)
@constraint(original_model, z[3] + z[4] <= 2)

@objective(original_model, Max, 3z[1] - z[2])


optimize!(original_model)
for i in 1:4
println("optimal z", i, ": ", value(z[i]))
end

optimal z1: 8.571428571428571


optimal z2: 0.42857142857142855
optimal z3: -1.0
optimal z4: 2.0
Coin0506I Presolve 0 (-6) rows, 0 (-4) columns and 0 (-11) elements
Clp3002W Empty problem - 0 rows, 0 columns and 0 elements
Clp0000I Optimal - objective value 25.285714
Coin0511I After Postsolve, objective 25.285714, infeasibilities - dual
0 (0), primal 0 (0)
Clp0032I Optimal objective 25.28571429 - 0 iterations time 0.002, Preso
lve 0.00
In [76]: A = [-1 6 -1 1 -1 0 0 0 0 0
0 7 0 1 0 0 0 0 0 0;
0 0 1 1 0 0 1 0 0 0;
0 1 0 0 0 0 0 1 0 0;
0 0 1 0 0 0 0 0 1 0;
0 0 0 1 0 0 0 0 0 1;
]
b = transpose([4 14 5 6 6 4])
SLP_model = Model(with_optimizer(Clp.Optimizer))
@variable(SLP_model, n[i=1:4] >= 0)
@variable(SLP_model, s[i=1:6] >= 0)
@constraint(SLP_model, con, A * [n;s] .== b)
@objective(SLP_model, Min, -3n[1] + 3s[1] +n[2] - 1)
optimize!(SLP_model)

Coin0506I Presolve 0 (-6) rows, 0 (-10) columns and 0 (-16) elements


Clp3002W Empty problem - 0 rows, 0 columns and 0 elements
Clp0000I Optimal - objective value -25.285714
Coin0511I After Postsolve, objective -25.285714, infeasibilities - dual
0 (0), primal 0 (0)
Clp0032I Optimal objective -25.28571429 - 0 iterations time 0.002, Pres
olve 0.00

In [69]: println("The optimal value for original problem is ",objective_value(SLP


_model))
for i in 1:4
println("Optimal n", i, " is ", value(n[i]))
end
for i in 1:6
println("Optimal s", i, " is ", value(s[i])) end

The optimal value for original problem is -25.28571428571429


Optimal n1 is 8.571428571428571
Optimal n2 is 1.4285714285714286
Optimal n3 is 0.0
Optimal n4 is 4.0
Optimal s1 is 0.0
Optimal s2 is 0.0
Optimal s3 is 1.0
Optimal s4 is 4.571428571428571
Optimal s5 is 6.0
Optimal s6 is 0.0

we also can use z1=n1-s1,z2=n2-1,z3=n3-1,z4=n4-2 to recover all the original zs.

In [ ]:

You might also like