# How to use elements of a N\*M elements Vector of Vector for a constraint

**URL:** <https://discourse.julialang.org/t/how-to-use-elements-of-a-n-m-elements-vector-of-vector-for-a-constraint/85295>\
**Category:** Optimization (Mathematical)\
**Tags:** question, jump\
**Created:** [August 4, 2022, 11:30am UTC](https://discourse.julialang.org/t/how-to-use-elements-of-a-n-m-elements-vector-of-vector-for-a-constraint/85295 "2022-08-04T11:30:12Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Optimization](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/optimization/32/32462_2.png) [@Optimization](https://discourse.julialang.org/u/Optimization)\
**Post date:** [August 4, 2022, 11:30am UTC](https://discourse.julialang.org/t/how-to-use-elements-of-a-n-m-elements-vector-of-vector-for-a-constraint/85295/1 "2022-08-04T11:30:12Z")

</div>

Hi,

We have two sets `A = [1,2,...,N]` and `B = [1,2,...,M]`. There are two other sets `SA, SB` associated with `A` and `B`which are N-elements and M-elemets vector of vector.

```julia
A = [1:N]
B = [1:M]

SA = [[some stuff for 1] , [some stuff for 2] ,..., [[some stuff for N] ]  
SB = [[some stuff for 1] , [some stuff for 2] ,..., [[some stuff for M] ]  

```

I’m interested in the intersection of things between `SA` and `SB` to later use them for a constraint.  
Therefore I did the following:

```julia
AB = [(a,b) for a in A for b in B]
SAB = [intersect( SA[a], SB[b]) for (a,b) in AB]

```

This outputs N\*M elements Vector of Vector. Until this point things are fine. Now I’d like to add a constrains to model that says:

```julia
sum( a in A , y[i, a, b]) <= U*x[i,j,b] for all b in B and i in SAB and j in SAB # where U is a constant

```

Therefore I translate it like below:

```julia
@constraint(model, [(a,b) in AB, i in SAB[a,b], j in SAB[a,b]], sum( y[i,a,b] for a in A) <= U * x[i,j,b]) 

```

But it return error like `KeyError: key (this, this, this) not found`. Next time I tried this

```julia
@constraint(model, [(b in B, i in SAB[a,b], j in SAB[a,b]], sum( y[i,a,b] for a in A) <= U * x[i,j,b]) 

```

Altough I knew it’s incorrect, but the only issue is that I cannot say `i in SAB[a,b]` when I only use ` [(b in B, i in SAB[a,b], j in SAB[a,b]]` Right??

Basically, how we could do this? Sum over `b` while using elements of sahred vector like `SAB`?

---

<div class="post-metadata">

**Author:** ![ikirill](https://avatars.discourse-cdn.com/v4/letter/i/43a26b/32.png) [@ikirill](https://discourse.julialang.org/u/ikirill)\
**Post date:** [August 5, 2022, 3:03am UTC](https://discourse.julialang.org/t/how-to-use-elements-of-a-n-m-elements-vector-of-vector-for-a-constraint/85295/2 "2022-08-05T03:03:56Z")

</div>

You could instead try to collect the constraint indices into a separate vector first, and just work around this:

```julia
julia> constraint_index = Any[]
Any[]

julia> for (a,b) in AB, i in SAB[a,b], j in SAB[a,b]; push!(constraint_index, (;a,b,i,j)); end

julia> constraint_index
4-element Vector{Any}:
 (a = 1, b = 4, i = 1, j = 1)
 (a = 2, b = 1, i = 2, j = 2)
 (a = 2, b = 3, i = 2, j = 2)
 (a = 3, b = 4, i = 4, j = 4)

```

If you don’t use the macro to parse the constraint indices, then using such an array of tuples seems like it’s easier:

```julia
julia> @constraint(model, c[(;a,b,i,j) in constraint_index], sum(y[i,a,b] for a in A) <= x[i,j,b])
1-dimensional DenseAxisArray{ConstraintRef{Model, MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64}, MathOptInterface.LessThan{Float64}}, ScalarShape},1,...} with index sets:
    Dimension 1, Any[(a = 1, b = 4, i = 1, j = 1), (a = 2, b = 1, i = 2, j = 2), (a = 2, b = 3, i = 2, j = 2), (a = 3, b = 4, i = 4, j = 4)]
And data, a 4-element Vector{ConstraintRef{Model, MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64}, MathOptInterface.LessThan{Float64}}, ScalarShape}}:
 c[(a = 1, b = 4, i = 1, j = 1)] : y[1,1,4] + y[1,2,4] + y[1,3,4] - x[1,1,4] ≤ 0.0
 c[(a = 2, b = 1, i = 2, j = 2)] : y[2,1,1] + y[2,2,1] + y[2,3,1] - x[2,2,1] ≤ 0.0
 c[(a = 2, b = 3, i = 2, j = 2)] : y[2,1,3] + y[2,2,3] + y[2,3,3] - x[2,2,3] ≤ 0.0
 c[(a = 3, b = 4, i = 4, j = 4)] : y[4,1,4] + y[4,2,4] + y[4,3,4] - x[4,4,4] ≤ 0.0

julia> c[(a=1,b=4,i=1,j=1)]
c[(a = 1, b = 4, i = 1, j = 1)] : y[1,1,4] + y[1,2,4] + y[1,3,4] - x[1,1,4] ≤ 0.0

```

You can index into the vector of constraints by arbitrary tuples this way.

(I used some arbitrary arrays A,B,etc., I hope I understood your example.)

I’m really not sure that the macro is even intended to parse complex for-loops like that in the index set, I think it’s just trying to figure out the dimensions of an array and failing.

---

<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:** [August 5, 2022, 9:55pm UTC](https://discourse.julialang.org/t/how-to-use-elements-of-a-n-m-elements-vector-of-vector-for-a-constraint/85295/3 "2022-08-05T21:55:11Z")

</div>

It’s hard to tell what’s going wrong without a reproducible example. For example, it’s not obvious what `SAB[a, b]` is. Isn’t `SAB` a vector? Do you mean `SAB = Dict((a, b) => intersect( SA[a], SB[b]) for (a,b) in AB)` and then `SAB[(a, b)]`?

But @ikirill’s suggestion of collating the indices is a good one. Don’t feel you need to be constrained by the helper syntax that JuMP provides. It’s a helper, but there are other ways if things are more complicated.

---

<div class="post-metadata">

**Author:** ![Optimization](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/optimization/32/32462_2.png) [@Optimization](https://discourse.julialang.org/u/Optimization)\
**Post date:** [August 7, 2022, 8:15am UTC](https://discourse.julialang.org/t/how-to-use-elements-of-a-n-m-elements-vector-of-vector-for-a-constraint/85295/4 "2022-08-07T08:15:32Z")

</div>

Thanks @ikirill this is very fresh to me. Nice to learn that. I did try it but I still have key error. There’s something wrong that is very uncelar why!! But thanks a lot. It is very inetersting.

I guess, the issue is realted to the `sum` part (`sum(y[i,a,b] for a in A)`. When I ran the exact things as yours. It says: `KeyError: key (661, 15, 14) not found`. which is one of the combinations of `(i,a,b)`. I mean it seems when summing over `a in A` there are some `(i,a,b)` which did not form by `constraint_index`

---

<div class="post-metadata">

**Author:** ![Optimization](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/optimization/32/32462_2.png) [@Optimization](https://discourse.julialang.org/u/Optimization)\
**Post date:** [August 7, 2022, 8:21am UTC](https://discourse.julialang.org/t/how-to-use-elements-of-a-n-m-elements-vector-of-vector-for-a-constraint/85295/5 "2022-08-07T08:21:37Z")

</div>

Thank @odow. Yes. They are like this

```julia
AB = [(a,b) for a in A for b in B]
sAB = [intersect(SA[a], SB[b]) for (a,b) in AB)]
SAB = Dict( AB .=> sAB)

```

---

<div class="post-metadata">

**Author:** ![jd-foster](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jd-foster/32/35824_2.png) [@jd-foster](https://discourse.julialang.org/u/jd-foster)\
**Post date:** [August 7, 2022, 12:28pm UTC](https://discourse.julialang.org/t/how-to-use-elements-of-a-n-m-elements-vector-of-vector-for-a-constraint/85295/6 "2022-08-07T12:28:50Z")

</div>

The question is harder to understand fully because you haven’t stated which indexing you’ve defined for `x` and `y`.

> [@Optimization](#):
>
> `@constraint(model, [(a,b) in AB, i in SAB[a,b], j in SAB[a,b]], sum( y[i,a,b] for a in A) <= U * x[i,j,b]) `

There are two _scopes_ happening here, where the index `a` appears in two places: first, in `(a,b) in AB` and then inside the `sum( ... for a in A)`. I would say that you probably want to write this as

```julia
@constraint(model, 
  [(a,b) in AB, i in SAB[a,b], j in SAB[a,b]], 
  sum( y[i,aa,b] for aa in A if aa == a) <= U * x[i,j,b]
)

```

A full minimal working example to test might look like this; you would help a lot by creating a similar one for future discussions:

```julia
using JuMP
model = JuMP.Model()

A = 1:4
B = 1:3
AB = [(a,b) for a in A for b in B]

SA = Dict([i => 10*i:10*(i+1) for i in A])
SB = Dict([i => [10*(i-1), 10*(i+2)] for i in B])
SAB = Dict((a, b) => intersect( SA[a], SB[b]) for (a,b) in AB)

SAB_vals = union(values(SAB)...)

@variable(model, x[i=SAB_vals, j=SAB_vals, b=B])
@variable(model, y[i=SAB_vals, a=A, b=B])

U = 7

@constraint(model, 
  [(a,b) in AB, i in SAB[a,b], j in SAB[a,b]], 
  sum( y[i,aa,b] for aa in A if aa == a) <= U * x[i,j,b]
)

```
