# What is the best way to separate out indices of a variable?

Hi guys,

What do you recommend to do in this situation?

I have a set `M` consisting of three separate sets of vectors of various size. In other words `M = [m_1, m_2, m_3] ` where `m_i` are vectors of different sizes. For instance `m_1` could be `1:10` while `m_2 = 22:65` and `m_3 = 100:123`(these are separate, no intersection in their elements).

with that, there need to have a variable `x[i,j,m]` to have some constraints as the following:

``````# N is a set which contains all net nodes
# x,z are variables

x[i,j,m] >= z[i,j]    for all i,j in N and m in M
``````

Now, we have another variables that are only defined on `m_i` like `y[i,j,m_1]`. So, at some points in some constraints, there’s only need to put condition over a subset of `M` (not all of its components). Similar to the following:

``````#I'm not writing like julia-- more like math version

sum(x[i,j,m] for i in N) <= y[i, m]   for all  j in N and m in m_1
``````

I did try to do this by:

``````@constraint(model, [j in N, m in m_1], sum( x[i,j,m]  for i in N) <=  y[i, m] )
``````

This is not working though. Do you know how to do this? having a variables that can act both over the whole set `M` and also act locally over just `m_1` or just `m_2`
I’m not sure if the issue is variable either. What I need to find out is that how to have flexible variable `x` that can handle `M` and `m_1` at the same time.

Thanks all!

I think you need something like this:

``````M = [1:2, 4:5, 7:8]
model = Model()
all_M = unique(reduce(vcat, M))
@variable(model, x[all_M])
@expression(model, sum(x[m] for m in all_M))
@expression(model, sum(x[m] for m in M))
``````

What probably happened is that it used `m_1`, `m_2`, an `m_3` as the keys of the variable, not the values of the `m_` vectors as the keys.

1 Like

Thanks @odow This works fine when you only have one index for `x`, but when having `x[i,j,m]` it has some issue unless I change the way I defined variable (redefine them over set vs. tuples).

One thing that I’d like to know is that once you need to impose condition over your indices what is the best practice? I usually define variable over tuples. But not sure whether there’s any better (or difference) to write a variable like this:

``````m = Model();
I = [1: n_i]  # n_  is just an integer number
J = [1: n_j]
M = [1: n_m]

@variable(m, x[I,J,M] >= 0 , Bin);
``````

Versus

``````m = Model();
I = [1: n_i]  # n_  is just an integer number
J = [1: n_j]
M = [1: n_m]

x_indices = [(i,j,m) for i in I  for j in J for m in M]
@variable(model, x[x_indices] >= 0, Bin)
``````

Perhaps there’s a good practice that I’m unaware of it. But as a beginner I’m hungry to learn. So please recommend me one if there exist. Thanks!

I would say that the former is better for a single `@variable` declaration, since you’re not allocating an intermediate array (`x_indices`) but allowing JuMP to generate variables directly from your separate index sets. The latter is virtually equivalent but necessary if reusing an index set like `x_indices` in multiple locations.

There is the concept of generating values on demand in general in Julia: Generator Expressions.

2 Likes

Thanks for your info and the link @jd-foster I’ll check it out!

1 Like