# Conditional Constraint Construction Based on Input Data Presence/Absence of Set Combinations in Julia JUMP

**URL:** <https://discourse.julialang.org/t/conditional-constraint-construction-based-on-input-data-presence-absence-of-set-combinations-in-julia-jump/103717>\
**Category:** Optimization (Mathematical)\
**Tags:** optimization\
**Created:** [September 10, 2023, 11:19am UTC](https://discourse.julialang.org/t/conditional-constraint-construction-based-on-input-data-presence-absence-of-set-combinations-in-julia-jump/103717 "2023-09-10T11:19:02Z")\
**Posts on this page:** 1\
**Showing post:** 2

<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:** [September 10, 2023, 10:53pm UTC](https://discourse.julialang.org/t/conditional-constraint-construction-based-on-input-data-presence-absence-of-set-combinations-in-julia-jump/103717/2 "2023-09-10T22:53:02Z")

</div>

This question has come up a few times recently ([Suggestions for documentation improvements · Issue #2348 · jump-dev/JuMP.jl · GitHub](https://github.com/jump-dev/JuMP.jl/issues/2348#issuecomment-1707515885)), so I definitely need to write some guidance on transitioning from GAMS to JuMP.

Can you provide a reproducible example of what you currently have, as well as the input data file? I’ll have a go to see how I would write your model.

Transitioning from GAMS to JuMP is a little complicated, because of the way we differ in handling data.

For example, GAMS lets you create “dense” sets and variables, and then index them using for-if loops. This means a direct translation of your GAMS code would try to look like:

```julia
model = Model()
@variable(model, x[A, B])
@constraint(model, [a in A], sum(x[a, b] for b in B if something(a, b)) == 1)

```

If there are very few values of `a` and `b` for which `something(a, b)` is `true` (that is, `x` is sparse), then this approach is inefficient because it requires a loop over every element in `B` for every element in `A`, just to throw away most of the work because `something(a, b) == false`.

The for-if approach works in GAMS because behind the scenes, GAMS translates this into a much more efficient format using relational algebra. But the for-if approach doesn’t work in JuMP because we don’t do the translation.

One approach is to only create variables for which the result is non-zero:

```julia
a_to_b = Dict(a => [] for a in A)
for a in A, b in B
    if something(a, b)
        push!(a_to_b[a], b)
    end
end
model = Model()
@variable(model, x[a in A, b in a_to_b[a]])
@constraint(model, [a in A], sum(x[a, b] for b in a_to_b[a]) == 1)

```

The other approach is to change your data structure to something like a `DataFrame`:

```plaintext
import DataFrames
df = DataFrames.DataFrame([(a = a, b = b) for a in A, b in B if something(a, b)])
model = Model()
df.x = @variable(model, x[1:size(df, 1)])
for gdf in DataFrames.groupby(df, [:a])
    @constraint(model, sum(gdf.x) == 1)
end

```

Here are some other links:

- [JuMP, GAMS, and the IJKLM model | JuMP](https://jump.dev/2023/07/20/gams-blog/)
- [Creating Variables from a Vector of Tuples and Naming Them - #4 by odow](https://discourse.julialang.org/t/creating-variables-from-a-vector-of-tuples-and-naming-them/103525/4)
- [julia - JuMP looping through and matching two different objects - Stack Overflow](https://stackoverflow.com/questions/77037132/jump-looping-through-and-matching-two-different-objects/77040465)
- [The network multi-commodity flow problem · JuMP](https://jump.dev/JuMP.jl/dev/tutorials/linear/multi_commodity_network/)

---

_[View the full topic](https://discourse.julialang.org/t/conditional-constraint-construction-based-on-input-data-presence-absence-of-set-combinations-in-julia-jump/103717)._
