# Run time constraints in optimisation

**URL:** <https://discourse.julialang.org/t/run-time-constraints-in-optimisation/47657>\
**Category:** Optimization (Mathematical)\
**Tags:** jump, optimization, argument\
**Created:** [October 2, 2020, 6:02pm UTC](https://discourse.julialang.org/t/run-time-constraints-in-optimisation/47657 "2020-10-02T18:02:36Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![JohnZ](https://avatars.discourse-cdn.com/v4/letter/j/ba8739/32.png) [@JohnZ](https://discourse.julialang.org/u/JohnZ)\
**Post date:** [October 2, 2020, 6:02pm UTC](https://discourse.julialang.org/t/run-time-constraints-in-optimisation/47657/1 "2020-10-02T18:02:37Z")

</div>

In an optimisation problem, I have some variables which must take same values. A simple example is given below where the optimisation variables with a unique identifier should have same values:

```julia
using DataFrames
using JuMP
using Clp

function generate_data()
df = DataFrame("SN" => (1:10),"Unique_ID"=> ["A","B","A","B","C","D","E","F","G","A"],
                       "Sector" => ["Priv", "Gov", "Utl", "Priv","Priv","Gov","Utl","Priv","Priv","Gov"],
                       "Values" => vec(float(rand(20:140,10,1))))
end

function build_model()
model = Model(Clp.Optimizer)
@variable(model,x[1:length(c)]>=0)
@objective(model,Min,sum(x[i]*c[i] for i = 1:length(c)))
@constraint(model,con1,sum(x[i] for i = 1:length(c))==1)
@constraint(model,con2,sum(x[i]*c[i] for i = 1:length(c))>=100)
return model,x
end

function run_model()
generate_data()
c = df.Values
build_model()
optimize!(model)
println("Results",JuMP.value.(x))
end

```

A workaround is to sort the data by the Unique ID and then setting the values of the optimization variables with unique ID equal to a variable t as shown below:

```julia
function run_model2()
generate_data()
sort!(df,"Unique_ID")
c = df.Values
model, x = build_model()
# Define a varible to set values of Unique ID equal 
@variable(model,t[1:2])
for i in 1:3
    @constraint(model,x[i]-t[1] ==0)
end
for i in 4:5
     @constraint(model,x[i]-t[2] ==0)
end
optimize!(model)
println("Results",JuMP.value.(x))
end

```

This is certainly not the best way of doing it and it is very manual. **1.What’s the recommended way of enforcing this constraint, ie. variables with the same unique ID should have same values?**  
I would like some (optional) constraints to be defined at the run time, such as some constraints to be applied only if an option is selected and/or values of some variables to be fixed when calling the run function. For example, I would like a constraint based on sector such that sum of values of x in a sector should not be greater than or equal to a value defined at the run time, and also the option to fix values of some variables. **2. How should I define the run function to define these optional constraints?**

My attempts at doing it are given below, but it contains errors. I do not understand how to set the optional arguments of the run\_model function to a default value and also that default value or a user defined value will only apply if argument is Yes for the if condition.

```julia
function run_model3(limit::string,fix::string)
generate_data()
if limit = "Yes"
    sort!(df,"Sector")
    c = df.Values
    model, x = build_model()
    @constraint(model,sum(x[i] for i =1:3)<=0.3)
    @constraint(model,sum(x[i] for i =4:9)<=0.3)
else
    c = df.Values
    model, x = build_model()
end
if fix="Yes"
    JuMP.fix.value(x[1]=0.1,force=true)
    c = df.Values
    model, x = build_model()
end
c = df.Values
model, x = build_model()
optimize!(model)
println("Results",JuMP.value.(x))
end

```

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [October 3, 2020, 1:17am UTC](https://discourse.julialang.org/t/run-time-constraints-in-optimisation/47657/2 "2020-10-03T01:17:00Z")

</div>

This should give you some ideas

```nohighlight
using DataFrames
using JuMP
using Clp

function generate_data()
    df = DataFrame(
        "SN" => (1:10),
        "Unique_ID"=> ["A","B","A","B","C","D","E","F","G","A"],
        "Sector" => ["Priv", "Gov", "Utl", "Priv","Priv","Gov","Utl","Priv","Priv","Gov"],
        "Values" => rand(20.0:140.0, 10),
    )
    return df
end

function build_model(c)
    model = Model(Clp.Optimizer)
    @variable(model, x[1:length(c)] >=0 )
    @objective(model, Min, sum(c[i] * x[i] for i = 1:length(c)))
    @constraint(model, con1, sum(x[i] for i = 1:length(c)) == 1)
    @constraint(model, con2, sum(c[i] * x[i] for i = 1:length(c)) >= 100)
    return model, x
end

function run_model(; fix_values = false)
    df = generate_data()
    model, x = build_model(df.Values)
    unique_keys = unique(df.Unique_ID)
    @variable(model, t[unique_keys])
    @constraint(model, [i = 1:length(x)], x[i] == t[df.Unique_ID[i]])
    if fix_values
        fix(x[1], 0.1; force = true)
    end
    optimize!(model)
    println("Results", JuMP.value.(x))
end

```

---

<div class="post-metadata">

**Author:** ![JohnZ](https://avatars.discourse-cdn.com/v4/letter/j/ba8739/32.png) [@JohnZ](https://discourse.julialang.org/u/JohnZ)\
**Post date:** [October 3, 2020, 1:18pm UTC](https://discourse.julialang.org/t/run-time-constraints-in-optimisation/47657/3 "2020-10-03T13:18:35Z")

</div>

That’s awesome! Thank you.

This does helps me to figure out answers to most of my questions.

I have not described it as clearly as it could be, there is one point that is still bugging me. That is how to make the code flexible so that at run time it accepts arguments to fix values of x by a defined number. For example, at run time the some or all of the following optional arguments could be specified, which should then trigger the if statement in the code to fix the values:

- `x[1]=0.1,x[2:4]=0.2,x[5]=0.1, x[6:7]=0.2` or
- `x[3]=0.3`

so the arguments are essentially a union of x[i]=fix\_value1 , x[i:n]= fixed\_value2

Do I need to define some custom types and use multiple dispatch, or wrap another function to deal with this? I am really lost!

I am wondering whether this should be asked as a separate question under the usage category as it may apply in broader situations and not just optimisation.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [October 3, 2020, 2:13pm UTC](https://discourse.julialang.org/t/run-time-constraints-in-optimisation/47657/4 "2020-10-03T14:13:41Z")

</div>

What do you mean by _run time_, exactly?

If _run time_ means _the time after creating the model but before calling `optimize!`_, then a simple [`JuMP.fix`](https://jump.dev/JuMP.jl/stable/variables/#JuMP.fix) should suffice.

If _run time_ means _in the middle of an call to `optimize!`_, then see [this post of mine.](https://discourse.julialang.org/t/how-to-make-if-in-the-objective-function/46859/13)

---

<div class="post-metadata">

**Author:** ![JohnZ](https://avatars.discourse-cdn.com/v4/letter/j/ba8739/32.png) [@JohnZ](https://discourse.julialang.org/u/JohnZ)\
**Post date:** [October 3, 2020, 2:29pm UTC](https://discourse.julialang.org/t/run-time-constraints-in-optimisation/47657/5 "2020-10-03T14:29:51Z")

</div>

> [@odow](#):
>
> `function run_model(; fix_values = false)`

By run time, I mean when calling the function to execute the code, ie function run\_model(; fix\_values = false) in @odow response. Basically when calling this function, I would like to have flexibility to fix values (optional) of variables which are to be specified as arguments to this function-so one does not have to and manually code them in the function before calling optimize!

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [October 3, 2020, 4:19pm UTC](https://discourse.julialang.org/t/run-time-constraints-in-optimisation/47657/6 "2020-10-03T16:19:57Z")

</div>

Could you check if this what you want?

```julia
function run_model(; vars_and_vals_to_fix = nothing)

```

and then

```julia
    ...
    if vars_and_vals_to_fix !== nothing
        vars, vals = vars_and_vals_to_fix
        fix.(vars, vals; force = true)
    end
    ...

```

to which you pass:

```julia
run_model(; vars_and_vals_to_fix = (x[1:7], [0.1, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2]))

```

---

<div class="post-metadata">

**Author:** ![JohnZ](https://avatars.discourse-cdn.com/v4/letter/j/ba8739/32.png) [@JohnZ](https://discourse.julialang.org/u/JohnZ)\
**Post date:** [October 3, 2020, 5:23pm UTC](https://discourse.julialang.org/t/run-time-constraints-in-optimisation/47657/7 "2020-10-03T17:23:09Z")

</div>

This is closer to what I want. The `run_model` function should be able to accept the arguments as you have set out, and additionally a combination of a range of x such as `x[1:7]` and a specific value say `x[8]` can be passed. Some examples below:

`run_model(; vars_and_vals_to_fix = (x[1:7], [0.1, 0.2, 0.2, 0.2, 0.1, 0.2,0.2],x[8],0.1))`  
`run_model(; vars_and_vals_to_fix = (x[1:7], [0.1, 0.2, 0.2, 0.2, 0.1, 0.2,0.2],x[9:10],[0.1,0.1]))`

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [October 3, 2020, 5:54pm UTC](https://discourse.julialang.org/t/run-time-constraints-in-optimisation/47657/8 "2020-10-03T17:54:25Z")

</div>

Unless it is too much of an overhead, my suggestion is to keep my code the way I wrote, and expand the ranges:

```julia
run_model(; vars_and_vals_to_fix = (vcat(x[1:7], x[9:10]), vcat([0.1, 0.2, 0.2, 0.2, 0.1, 0.2,0.2],[0.1,0.1])))

```

or

```julia
run_model(; vars_and_vals_to_fix = (vcat(x[1:7], x[9:10]), [0.1, 0.2, 0.2, 0.2, 0.1, 0.2,0.2, 0.1,0.1]))

```

If the overhead become too much I would recommend looking into `@view` and lazy iterators, but keeping this way of doing the things.

---

<div class="post-metadata">

**Author:** ![JohnZ](https://avatars.discourse-cdn.com/v4/letter/j/ba8739/32.png) [@JohnZ](https://discourse.julialang.org/u/JohnZ)\
**Post date:** [October 3, 2020, 8:05pm UTC](https://discourse.julialang.org/t/run-time-constraints-in-optimisation/47657/9 "2020-10-03T20:05:08Z")

</div>

Thanks
