22

12

2

6

# ParameterJuMP.jl

Build Status Social

A JuMP extension to use parameters in constraints constants.

## Welcome to ParameterJuMP

To enable the usage of ParameterJuMP the optimization model must be constructed with the function:

ModelWithParam(args...)


Which can receive the same inputs as the original Model constructor, and also returns the same Model type.

The key constructor of ParameterJuMP is:

add_parameter(model::JuMP.Model, value::Number)


Which adds a parameter fixed at value to the JuMP model model. It is possible to create multiple parameters at the same time with:

add_parameters(model::JuMP.Model, values::Vector{Number})


Which returns a vector of parameters.

It is possible to change the current value of a parameter with the function:

fix(p::ParameterRef, new_value::Number)


Finally, the dual function of JuMP is overloaded to return duals for parameters:

dual(p::ParameterRef)


Last but not least! The parameter algebra was implemented so that is possible to:

• sum two parameters
• multiply parameters by constants
• sum parameters and variables
• sum parameters and affine expressions

All the operations related to linear constraints are implemented.

### Simple example

min   x
s.t.  x >= a


where x is a variable and a is a constant. We can also solve it for different values of a.

# Create a JuMP model able to handle parameters
model = ModelWithParams(SOME_SOLVER.Optimizer)

# Create a regular JuMP variable
@variable(model, x)

# Create a parameter fixed at 10

# adds a constraint mixing variables and parameters to the model
@constraint(model, x >= a)

# solve the model
optimize!(model)

# query dual variable of the constant a
dual(a)

# modify the value of the parameter a to 20
fix(a, 20)

# solve the model with the new value of the parameter
optimize!(model)


## Installation

Currently ParameterJuMP works with Julia 1.x and JuMP 0.19.x

• type ] to go to the package manager
• type add https://github.com/JuliaStochOpt/ParameterJuMP.jl (because its currently not registered)

## Motivation

Suppose we have linear programming problem of the following form

$\begin{array}{ll}&space;\mbox{minimize}&space;&&space;c^\top&space;x\\&space;\mbox{subject&space;to}&space;&&space;Ax&space;&space;=&space;b&space;-&space;D&space;y&space;\\&space;&&space;x&space;\geq&space;0,&space;\end{array}$

The only decision variable in the problem is $x$. On the other hand, $y$ is a mere parameter.

Problems like this appear frequently in Stochastic optimization and in Decomposition frameworks.

In stochastic optimization it is frequent to solve that same problem for multiple values of $y$, which are tipically scenario dependent.

In decomposition frameworks, it is useful to solve the same problem for multiple values of $y$, but even more important is to be able to query dual values from $y$. This dual values are computed by applying the chain rule on the duals of the constraints.

### Pure JuMP version

In pure JuMP we can acomplish these tasks by creating dummy fixed variables, so that we can easily change their fixed values and query duals from fixing constraints.

One example in pure JuMP goes as follows:

# create a regular JuMP Model
model_pure = Model(SOME_SOLVER.Optimizer)

@variable(model_pure, x[1:N] >= 0)

@variable(model_pure, y[1:M])
@variable(model_pure, y_fixed[1:M] == value_for_y[i])
@constraint(model_pure, fix_y[j in 1:M], y[i] == y_fixed[i])

@constraint(model_pure, ctr[k in 1:P],
sum(A[i,k]*x[i] for i in 1:N) == b[k] - sum(D[j,k]*y[j] for j in 1:M))

# create objective function
@objective(model_pure, Min, sum(c[i]*x[i] for i in 1:N))

# solve problem
optimize!(model_pure)

# query dual values
y_duals = dual.(fix_y)

# modify y
fix.(y_fixed, new_value_for_y)

# solve problem (again)
optimize!(model_pure)

# query dual values (again)
y_duals = dual.(fix_y)


The main problem with this approach is that it creates to many dummy variables that are added without real need to the solver representation of the optimization problem. Hence solve times are increased without real need!!!

### ParameterJuMP version

The same example of the motivation can be written with parameters:

# create a regular JuMP Model
model_pure = Model(SOME_SOLVER.Optimizer)

@variable(model_pure, x[1:N] >= 0)

y = [add_parameter(model_pure, value_for_y[i]) for i in 1:M]
# or

@constraint(model_pure, ctr[k in 1:P],
sum(A[i,k]*x[i] for i in 1:N) == b[k] - sum(D[j,k]*y[j] for j in 1:M))

# create objective function
@objective(model_pure, Min, sum(c[i]*x[i] for i in 1:N))

# solve problem
optimize!(model_pure)

# query dual values
y_duals = dual.(y)

# modify y
fix.(y, new_value_for_y)

# solve problem (again)
optimize!(model_pure)

# query dual values (again)
y_duals = dual.(y)


## Acknowledgments

ParameterJuMP was developed by:

• Joaquim Dias Garcia (@joaquimg), PSR and PUC-Rio
• Benoît Legat (@blegat), UCLouvain

01/05/2018

5 days ago

142 commits