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:
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:
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.
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