# Variant of an "elseif" loop with binary values

Hi !

I’m looking for another possibility to implement my elseif loop for my linear program.
The goal is to implement the following:

``````if q_out >= 9
eff == 0.75
elseif 7 <= q_out < 9
eff == 1
else
eff == 0.5
end
``````

I have already implemented these lines of code (see an extract below).

``````set_optimizer_attribute(model, "NonConvex",2)

M = 10^(10) # parameter to select my binary variable

# definition of the variables
@variable(model, 0 <= q_out <= 15)
@variable(model, 0 <= eff <= 1)
@variable(model, 0 <= z_1 <= 1, binary=true)
@variable(model, 0 <= z_2 <= 1, binary=true)

# constraints
@constraint(model, q_out <= 7-0.1*10^(-1) + M * (1 - z_1))
@constraint(model, q_out >= 7-0.1*10^(-1) - M * z_1)

@constraint(model, q_out <= 9-0.1*10^(-1) + M * (1 - z_2))
@constraint(model, q_out >= 9-0.1*10^(-1)  - M * z_2)

@constraint(model, eff == 0.75 * (1-z_2) +  1*z_2 + (0.5-1)*z_1 )
``````

But I’m not convinced of its result.
When `q_out` approaches the limit 9, for example `q_out = 8.989999389648451`, my binary value `z_2=0.9999999999999933` is no longer binary, which is problematic for the variable `eff`.

Has somebody an idea of other possibilities to write my code to avoid this kind of problem?

I think it is expected binary/integer variables do not fulfil their constraint exactly for performance reasons. The details will depend on the solver used (example). If you want exact values then I suggest rounding with `round(Int, x)`

1 Like

Just to clarify, you cannot use `round(Int, x)` inside a JuMP model.

Gurobi has some helpful articles for understanding what is going on:

As suggested at the bottom of the last article, you could also use indicator constraints:

``````using JuMP, Gurobi
model = Model(Gurobi.Optimizer)
@variable(model, q_out)
@variable(model, eff)
@variable(model, z[1:3], Bin)
@constraint(model, sum(z) == 1)
@constraint(model, z --> {q_out >= 9})
@constraint(model, z --> {q_out >= 7})
@constraint(model, z --> {q_out <= 9})
@constraint(model, z --> {q_out <= 7})
@constraint(model, eff == 0.75 * z + 1.0 * z + 0.5 * z)
``````

(I haven’t tested this code, so there might be typos, etc.)

1 Like

Hi Odow,