# Condition constraint symbol on problem data

Here is a linear program I am trying to solve:

``````using JuMP
import GLPK

function LP_example(A::Array{Int64, 2}, B::Array{Int64, 2},
c::Array{Int64, 1})
n, m = size(B)
model = Model(GLPK.Optimizer)

# Constraint matrix is totally unimodular so no Bin constraint
@variable(model, 0 <= x[1:m, 1:n] <= 1)
@objective(model, Min, sum(x .* A))

if m <= n
@constraints(model, begin
smile[i in 1:n], sum(x[:, i]) <= 1			# Toggle these inequalities
frown[j in 1:m], sum(x[j, :]) == c[j]		# depending on whether m <= n
end)
else
@constraints(model, begin
smile[i in 1:n], sum(x[:, i]) == 1		 	#
frown[j in 1:m], sum(x[j, :]) >= c[j]		#
end)
end

optimize!(model)
out = value.(x)

# Also, is this the best way to double-check that soln is binary?
@assert isempty(filter(x -> !(round(x, digits=5) in [0, 1]), out)) "Solution not integral"

return out
end
``````

In the `if m <= n` block, the constraints are nearly identical, and the only difference is that the inequality and equality constraints switch signs.

Is there a way to avoid repeating the constraint expressions by conditioning around the comparison symbol only? Something like

``````smile[i in 1:n], sum(x[:, i]) (m <= n) ? (<=) : (==) 1
``````

The `if` statement is fine. Alternatively, you could do something like:

``````m, n = 3, 2
model = Model()
@variable(model, x[1:m, 1:n])
c = rand(m)  # Make sure `c` is `Vector{Float64}`!
set_smile = m <= n ? MOI.LessThan(1.0) : MOI.EqualTo(1.0)
set_frown(j) = m <= n ? MOI.EqualTo(c[j]) : MOI.GreaterThan(c[j])
@constraints(model, begin
smile[i=1:n], sum(x[:, i]) in set_smile
frown[j=1:m], sum(x[j, :]) in set_frown(j)
end)
``````

For checking whether something is binary, you could use

``````function is_binary(x; atol=1e-8)
return isapprox(x, 0; atol=atol) || isapprox(x, 1; atol=atol)
end

@assert all(is_binary, out)
``````
1 Like