julia 安装JuMP和Cplex

Installing JuMP¶

At first add the JuMP package by running the following code in the notebook:

In [2]:

Pkg.add("JuMP")
INFO: Nothing to be done

We need to install a solver package. Let's install the open source solvers GLPK, Cbc and Clp by typing in Pkg.add("GLPKMathProgInterface")Pkg.add("Cbc") and Pkg.add("Clp") respectively. Let's add the Julia package associated with CPLEX by typing in Pkg.add("CPLEX"). The other choices are "CPLEX""Cbc""Clp""Gurobi" and "MOSEK".

It should be noted that, in order to use commercial solvers such as CPLEX, Gurobi and Mosek in JuMP, we will require working installations of them with appropriate licences. Both Gurobi and Mosek are free for academic use. CPLEX is free for faculty members and graduate teaching assistants.

In [2]:

Pkg.add("GLPKMathProgInterface")
INFO: Nothing to be done

In [3]:

Pkg.add("Cbc")
INFO: Nothing to be done

In [4]:

Pkg.add("Clp")
INFO: Nothing to be done

In [5]:

Pkg.add("CPLEX") # Working installation of CPLEX is needed in advance
INFO: Nothing to be done

In [6]:

Pkg.add("Gurobi") # Working installation of Gurobi is needed in advance
INFO: Nothing to be done

If you have not updated your Julia packages in a while, a good idea might be updating them.

In [7]:

Pkg.update()
INFO: Updating METADATA...
INFO: Computing changes...
INFO: No packages to install, update or remove

In [13]:

println("Hello World!")
Hello World!

The very first example¶

At first let us try to solve a very simple and trivial optimization problem using JuMP to check if everything is working properly.

minimizesubject tox+yx+y≤1x≥0,y≥0x,y∈Rminimizex+ysubject tox+y≤1x≥0,y≥0x,y∈R

Here is the JuMP code to solve the mentioned problem:

In [3]:

using JuMP  # Need to say it whenever we use JuMP

using GLPKMathProgInterface # Loading the GLPK module for using its solver


#MODEL CONSTRUCTION
#--------------------

myModel = Model(solver=GLPKSolverLP()) 
# Name of the model object. All constraints and variables of an optimization problem are associated 
# with a particular model object. The name of the model object does not have to be myModel, it can be yourModel too! The argument of Model,
# solver=GLPKsolverLP() means that to solve the optimization problem we will use GLPK solver.

#VARIABLES
#---------

# A variable is modelled using @defVar(name of the model object, variable name and bound, variable type)
# Bound can be lower bound, upper bound or both. If no variable type is defined, then it is treated as 
#real. For binary variable write Bin and for integer use Int.

@defVar(myModel, x >= 0) # Models x >=0

# Some possible variations:
# @defVar(myModel, x, Binary) # No bound on x present, but x is a binary variable now
# @defVar(myModel, x <= 10) # This one defines a variable with lower bound x <= 10
# @defVar(myModel, 0 <= x <= 10, Int) # This one has both lower and upper bound, and x is an integer

@defVar(myModel, y >= 0) # Models y >= 0

#OBJECTIVE
#---------

@setObjective(myModel, Min, x + y) # Sets the objective to be minimized. For maximization use Max

#CONSTRAINTS
#-----------

@addConstraint(myModel, x + y <= 1) # Adds the constraint x + y <= 1

#THE MODEL IN A HUMAN-READABLE FORMAT
#------------------------------------
println("The optimization problem to be solved is:")
print(myModel) # Shows the model constructed in a human-readable form

#SOLVE IT AND DISPLAY THE RESULTS
#--------------------------------
status = solve(myModel) # solves the model  

println("Objective value: ", getObjectiveValue(myModel)) # getObjectiveValue(model_name) gives the optimum objective value
println("x = ", getValue(x)) # getValue(decision_variable) will give the optimum value of the associated decision variable
println("y = ", getValue(y))
The optimization problem to be solved is:
Min x + y
Subject to
 x + y <= 1
 x >= 0
 y >= 0
Objective value: 0.0
x = 0.0
y = 0.0

This was certainly not the most exciting optimization problem to solve. This was for test purpose only. However, before going into the structure of a JuMP model, let us learn how to represent vectors in Julia.

Representing vectors in Julia¶

  • A column vector, y=(y1,y2,…,yn)=⎛⎝⎜⎜⎜⎜⎜⎜y1y2..yn⎞⎠⎟⎟⎟⎟⎟⎟∈Rny=(y1,y2,…,yn)=(y1y2..yn)∈Rn will be written in Julia as [y[1];y[2];...;y[n]].

    For example to create column vector ⎛⎝⎜32.49.1⎞⎠⎟(32.49.1) use: [3; 2.4; 9.1].

In [19]:

[3; 2.4; 9.1] # Column vector

Out[19]:

3-element Array{Float64,1}:
 3.0
 2.4
 9.1
  • A row vector, z=(z1z2…zn)∈R1×nz=(z1z2…zn)∈R1×n will be written in Julia as [z[1] y[2]...z[n]].

    For example to create row vector (1.23.58.21)(1.23.58.21) use: [1.2 3.5 8.21].

In [11]:

[1.2 3.5 8.21] # Row vector

Out[11]:

1x3 Array{Float64,2}:
 1.2  3.5  8.21
  • To create a m×nm×n matrix

A=⎛⎝⎜A11…Am1A12…Am2A13…Am3………A1n…Amn⎞⎠⎟A=(A11A12A13…A1n……………Am1Am2Am3…Amn)

write:

[A[1,1] A[1,2] A[1,3]... A[1,n]; ... ; A[m,1] A[m,2] ... A[m,n]].

So the matrix

 

A=⎛⎝⎜1321509065813⎞⎠⎟A=(1195350820613)

is represented in Julia as:

`A= [ 1 1 9 5; 3 5 0 8; 2 0 6 13 ]`

In [12]:

# Generating a matrix
A= [
     1 1 9 5;
     3 5 0 8;
     2 0 6 13
    ]

Out[12]:

3x4 Array{Int64,2}:
 1  1  9   5
 3  5  0   8
 2  0  6  13

AijAij can be accessed by A[i,j] ,the iith row of the matrix A is represented by A[i,:], the jjth column of the matrix A is represented by A[:,j].

The size of a matrix AA can be determined by running the command size(A). If we write numRows, numCols = size(A), then numRows and numCols will contain the total number of rows and columns of A respectively.

In [13]:

numRows, numCols = size(A)
println(
"A has ", numRows, " rows and ", numCols, " columns \n",
"A[3,3] is ", A[3,3], "\n",
"The 3rd column of A is ", A[:,3], "\n",
"The 2nd row of A is ", A[2,:]
)
A has 3 rows and 4 columns 
A[3,3] is 6
The 3rd column of A is [9,0,6]
The 2nd row of A is [3 5 0 8]

Suppose x,y∈Rnx,y∈Rn. Then xTy=∑ni=1xiyixTy=∑i=1nxiyi is written as dot(x,y).

In [14]:

y=[1; 2; 3; 4]
x=[5; 6; 7; 8]
xTy=dot(x,y)

Out[14]:

70

Structure of a JuMP model¶

Any JuMP model that describes an optimization problem must have four parts:

  • Model Object,
  • Variables,
  • Objective,
  • Constraints.

Model¶

Any instance of an optimization problem corresponds to a model object. This model object is associated with all the variables, constraints and objective of the instance. It is constructed using modelName = Model(solver=solver of our preference). If no solver is specified, then ClpSolver() and/or CbcSolver() will be used by default. Here modelNameis any valid name. We will limit ourselves in the open source solvers such as:

  • Linear Programming Solver: ClpSolver(), GLPKSolverLP()
  • Mixed Integer Programming Solver: GLPKSolverMIP() CbcSolver()

In [2]:

using JuMP
myModel = Model() # ClpSolver() and/or CbcSolver() will be used based on the problem

Out[2]:

minSubject to0min0Subject to

Variables¶

Variables are defined using @defVar macro, which takes up to three input arguments. The first argument is the name of the model. Then the second argument contains the name of the variable, and a bound on the variable if it exists. The third argument is not needed if the variable is real. When the variable is binary or integer, then Bin or Int, respectively, is used in place of the third argument.

Examples of Variables¶

Suppose the model object is myModel.

  • To describe a variable z∈Rz∈R such that 0≤z≤100≤z≤10 write

In [4]:

@defVar(myModel, 0 <= z <= 10)

Out[4]:

zz

  • Now consider a decision variable x∈Rnx∈Rn, and it has a bound l⪯x⪯ul⪯x⪯u, where naturally l,u∈Rnl,u∈Rn. For that we write 

In [16]:

# INPUT DATA, CHANGE THEM TO YOUR REQUIREMENT
#-------------------------------------------
n = 10
l = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
u = [10; 11; 12; 13; 14; 15; 16; 17; 18; 19]

Out[16]:

10-element Array{Int64,1}:
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19

In [17]:

# VARIABLE DEFINITION
# ------------------- 
@defVar(myModel, l[i] <= x[i=1:n] <= u [i])

Out[17]:

..≤xi≤..∀i∈{1,2,…,9,10}..≤xi≤..∀i∈{1,2,…,9,10}

  • Suppose we have decision variables x∈Rnx∈Rn, y∈Zmy∈Zm and z∈{0,1}pz∈{0,1}p such that x⪰0x⪰0, a⪯y⪯ba⪯y⪯b. Here a,b∈Zma,b∈Zm. To express this in JuMP we write

In [18]:

# INPUT DATA, CHANGE THEM TO YOUR REQUIREMENT
#-------------------------------------------
n = 4 # dimension of x
m = 3 # dimension of y
p = 2 # dimensin of z
a = [0; 1; 2]
b = [3; 4; 7]

Out[18]:

3-element Array{Int64,1}:
 3
 4
 7

In [19]:

# VARIABLE DEFINITION
# -------------------
@defVar(myModel, x[i=1:n] >= 0)

Out[19]:

xi≥0∀i∈{1,2,3,4}xi≥0∀i∈{1,2,3,4}

In [20]:

@defVar(myModel, a[i] <= y[i=1:m] <= b[i], Int)

Out[20]:

..≤yi≤..,∈Z,∀i∈{1,2,3}..≤yi≤..,∈Z,∀i∈{1,2,3}

In [21]:

@defVar(myModel, z[i=1:p], Bin)

Out[21]:

zi∈{0,1}∀i∈{1,2}zi∈{0,1}∀i∈{1,2}

Constraints¶

Constraints are added by using @addConstraint macro. The first argument is the model object the constraint is associated with, the second argument is the reference to that constraint and the third argument is the constraint description. The constraint reference comes handy when we want to manipulate the constraint later or access the dual variables associated with it. If no constraint reference is needed, then the second argument is the constraint description. 

Examples of Constraints¶

Let's give some examples on writing constraints in JuMP. Suppose the model name is yourModel.

In [5]:

yourModel = Model()

Out[5]:

minSubject to0min0Subject to

  1. Consider variables x,y∈Rx,y∈R which are coupled by the constraints 5x+3y≤55x+3y≤5. We write this as 
    @addConstraint(yourModel, 5*x + 3*y <= 5) 
    Naturally, x and y have to be defined first using @defVar macro.

In [6]:

@defVar(yourModel, x)
@defVar(yourModel, y)
@addConstraint(yourModel, 5*x + 3*y <= 5)

Out[6]:

5x+3y≤55x+3y≤5

Here no constraint reference is given. Now suppose we want to get the dual value of some constraint after solving the problem, then we would need a constraint reference to assign to the constraint first. Let's call the constraint reference as conRef1 (it could be any valid name). Then the same constraint have to be written as: 
@addConstraint(yourModel, conRef1, 6*x + 4*y >= 5) 
When we would need the dual value after solving the problem we just write println(getDual(conRef1))

In [7]:

@addConstraint(yourModel, conRef1, 6*x + 4*y >= 5)

Out[7]:

6x+4y≥56x+4y≥5

  1. Consider a variable x∈R4x∈R4, a coefficient vector a=(1,−3,5,−7)a=(1,−3,5,−7) We want to write a constraint of the form ∑4i=1aixi≤3∑i=14aixi≤3. In JuMP we write:

In [8]:

a = [1; -3; 5; 7] 
@defVar(yourModel, w[1:4])
@addConstraint(yourModel, sum{a[i]*w[i],i=1:4} <= 3)

Out[8]:

w1−3w2+5w3+7w4≤3w1−3w2+5w3+7w4≤3

Objective¶

Objective is set using @setObjective macro. It has three arguments. The first argument is as usual the model object. The second one is either Max if we want to maximize the objective function, or Min when we want to minimize. The last argument is the description of the objective which has similar syntax to that of constraint definition.

Example of objective¶

For the previous model, consider the decision variable w∈R4w∈R4 and cost vector c=(2,3,4,5)c=(2,3,4,5). We want to minimize cTwcTw. In JuMP we would write:

In [10]:

c = [2; 3; 4; 5] 
@setObjective(yourModel, Min, sum{c[i]*w[i],i=1:4})

Out[10]:

2w1+3w2+4w3+5w42w1+3w2+4w3+5w4

Solving a standard form Linear Programming¶

problem Let us try to write the JuMP code for the following standard form optimization problem:

minimizesubject tocTxAx=bx⪰0x∈RnminimizecTxsubject toAx=bx⪰0x∈Rn

where, n=4n=4, c=(1,3,5,2)c=(1,3,5,2), A=(1195 3508 20613)A=(1195 3508 20613) and b=(7,3,5)b=(7,3,5). The symbol ⪰⪰ (⪯⪯) stands for element-wise greater (less) than or equal to.

Entering different parts of the code one by one¶

Let us input different parts of the JuMP code one by one and see the corresponding outputs to detect if everything is okay. Of course we could input the whole code at once.

In [72]:

using JuMP  # Need to say it whenever we use JuMP

using GLPKMathProgInterface # Loading the package for using the GLPK solver

In [74]:

#MODEL CONSTRUCTION
#------------------

sfLpModel = Model(solver=GLPKSolverLP()) # Name of the model object

Out[74]:

minSubject to0min0Subject to

In [75]:

#INPUT DATA
#----------

c = [1; 3; 5; 2] 

A= [
     1 1 9 5;
     3 5 0 8;
     2 0 6 13
    ]

b = [7; 3; 5] 

m, n = size (A) # m = number of rows of A, n = number of columns of A

Out[75]:

(3,4)

In [76]:

#VARIABLES
#---------

@defVar(sfLpModel, x[1:n] >= 0) # Models x >=0

Out[76]:

xi≥0∀i∈{1,2,3,4}xi≥0∀i∈{1,2,3,4}

In [77]:

#CONSTRAINTS
#-----------

for i=1:m # for all rows do the following
    @addConstraint(sfLpModel, sum{A[i,j]*x[j] , j=1:n} == b[i]) # the ith row 
    # of A*x is equal to the ith component of b
end # end of the for loop

In [78]:

#OBJECTIVE
#---------

@setObjective(sfLpModel, Min, sum{c[j]*x[j], j=1:n}) # minimize c'x

Out[78]:

x1+3x2+5x3+2x4x1+3x2+5x3+2x4

In [79]:

#THE MODEL IN A HUMAN-READABLE FORMAT
#------------------------------------

println("The optimization problem to be solved is:")
print(sfLpModel) # Shows the model constructed in a human-readable form
The optimization problem to be solved is:
Min x[1] + 3 x[2] + 5 x[3] + 2 x[4]
Subject to
 x[1] + x[2] + 9 x[3] + 5 x[4] == 7
 3 x[1] + 5 x[2] + 8 x[4] == 3
 2 x[1] + 6 x[3] + 13 x[4] == 5
 x[i] >= 0 for all i in {1,2,3,4}

In [80]:

status = solve(sfLpModel) # solves the model

Out[80]:

:Optimal

In [81]:

#SOLVE IT AND DISPLAY THE RESULTS
#--------------------------------

println("Objective value: ", getObjectiveValue(sfLpModel)) # getObjectiveValue(model_name) gives the optimum objective value

println("Optimal solution is x = \n", getValue(x)) # getValue(decision_variable) will give the optimum value 
                                                   # of the associated decision variable
Objective value: 4.923076923076923
Optimal solution is x = 
[1] = 0.4230769230769228
[2] = 0.34615384615384626
[3] = 0.6923076923076923
[4] = 0.0

The whole code¶

In [5]:

using JuMP  

using GLPKMathProgInterface 

#MODEL CONSTRUCTION
#------------------

sfLpModel = Model(solver=GLPKSolverLP())

#INPUT DATA
#----------

c = [1; 3; 5; 2] 

A= [
     1 1 9 5;
     3 5 0 8;
     2 0 6 13
    ]

b = [7; 3; 5] 

m, n = size (A) # m = number of rows of A, n = number of columns of A

#VARIABLES
#---------

@defVar(sfLpModel, x[1:n] >= 0) # Models x >=0

#CONSTRAINTS
#-----------

for i=1:m # for all rows do the following
    @addConstraint(sfLpModel, sum{A[i,j]*x[j] , j=1:n} == b[i]) # the ith row 
    # of A*x is equal to the ith component of b
end # end of the for loop

#OBJECTIVE
#---------

@setObjective(sfLpModel, Min, sum{c[j]*x[j], j=1:n}) # minimize c'x 



#THE MODEL IN A HUMAN-READABLE FORMAT
#------------------------------------

println("The optimization problem to be solved is:")
print(sfLpModel) # Shows the model constructed in a human-readable form

@time begin
status = solve(sfLpModel) # solves the model  
end
#SOLVE IT AND DISPLAY THE RESULTS
#-------------------------------- 

println("Objective value: ", getObjectiveValue(sfLpModel)) # getObjectiveValue(model_name) gives the optimum objective value

println("Optimal solution is x = \n", getValue(x)) # getValue(decision_variable) will give the optimum value 
                                                   # of the associated decision variable
The optimization problem to be solved is:
Min x[1] + 3 x[2] + 5 x[3] + 2 x[4]
Subject to
 x[1] + x[2] + 9 x[3] + 5 x[4] == 7
 3 x[1] + 5 x[2] + 8 x[4] == 3
 2 x[1] + 6 x[3] + 13 x[4] == 5
 x[i] >= 0 for all i in {1,2,3,4}
elapsed time: 0.000363692 seconds (6792 bytes allocated)
Objective value: 4.923076923076923
Optimal solution is x = 
x: 1 dimensions:
[1] = 0.4230769230769228
[2] = 0.34615384615384626
[3] = 0.6923076923076923
[4] = 0.0

Solving a standard form Mixed Integer Programming Problem¶

Let us try to write the JuMP code for the following standard form optimization problem:

minimizesubject tocTx+dTyAx+By=fx⪰0,y⪰0x∈Rn,y∈ZpminimizecTx+dTysubject toAx+By=fx⪰0,y⪰0x∈Rn,y∈Zp

Here, A∈Rm×n,B∈Rm×p,c∈Rn,d∈Rp,f∈RmA∈Rm×n,B∈Rm×p,c∈Rn,d∈Rp,f∈Rm. The data were randomly generated. The symbol ⪰⪰ (⪯⪯) stands for element-wise greater (less) than or equal to.

In [27]:

n = 5
p = 4
m = 3
A=
[0.7511 -0.1357   0.7955  -0.4567 0.1356
-0.6670 -0.3326   0.1657  -0.5519 -0.9367
 1.5894 -0.1302  -0.4313  -0.4875  0.4179]

B=
[-0.09520 -0.28056 -1.33978 0.6506
 -0.8581  -0.3518   1.2788  1.5114
 -0.5925  1.3477    0.1589  0.03495]

c=[0.3468,0.8687,0.1200,0.5024,0.2884]

d=[0.2017,0.2712,0.4997,0.9238]

f = [0.1716,0.3610,0.0705]

Out[27]:

3-element Array{Float64,1}:
 0.1716
 0.361 
 0.0705

In [28]:

using JuMP
using GLPKMathProgInterface

sfMipModel = Model(solver = GLPKSolverMIP())

@defVar(sfMipModel, x[1:n] >=0)
@defVar(sfMipModel, y[1:p] >= 0, Int)

@setObjective(sfMipModel, Min, sum{c[i] * x[i], i in 1:n}+sum{d[i]*y[i], i in 1:p})

for i in [1:m]
    @addConstraint(sfMipModel, sum{A[i,j]*x[j], j in [1:n]}+ sum{B[i,j]*y[j], j in [1:p]} == f[i])
end

print(sfMipModel, "\n")
statusMipModel = solve(sfMipModel)
print("Status of the problem is ", statusMipModel, "\n")

if statusMipModel == :Optimal
    print ("Optimal objective value = ", getObjectiveValue(sfMipModel), "\nOptimal x = ", getValue(x), "\nOptimal y = ", getValue(y))
end
Min 0.3468 x[1] + 0.8687 x[2] + 0.12 x[3] + 0.5024 x[4] + 0.2884 x[5] + 0.2017 y[1] + 0.2712 y[2] + 0.4997 y[3] + 0.9238 y[4]
Subject to
 0.7511 x[1] - 0.1357 x[2] + 0.7955 x[3] - 0.4567 x[4] + 0.1356 x[5] - 0.0952 y[1] - 0.28056 y[2] - 1.33978 y[3] + 0.6506 y[4] == 0.1716
 -0.667 x[1] - 0.3326 x[2] + 0.1657 x[3] - 0.5519 x[4] - 0.9367 x[5] - 0.8581 y[1] - 0.3518 y[2] + 1.2788 y[3] + 1.5114 y[4] == 0.361
 1.5894 x[1] - 0.1302 x[2] - 0.4313 x[3] - 0.4875 x[4] + 0.4179 x[5] - 0.5925 y[1] + 1.3477 y[2] + 0.1589 y[3] + 0.03495 y[4] == 0.0705
 x[i] >= 0 for all i in {1,2..4,5}
 y[i] >= 0, integer, for all i in {1,2,3,4}

Status of the problem is Optimal
Optimal objective value = 1.070277955983598
Optimal x = x: 1 dimensions:
[1] = 0.0654906726037024
[2] = 0.0
[3] = 1.6298599862096397
[4] = 0.0
[5] = 1.221506908389311

Optimal y = y: 1 dimensions:
[1] = 0.0
[2] = 0.0
[3] = 1.0
[4] = 0.0

Reference¶

[1] M. Lubin and I. Dunning, “Computing in Operations Research using Julia”, INFORMS Journal on Computing, to appear, 2014. arXiv:1312.1431

你可能感兴趣的:(julia 安装JuMP和Cplex)