Loop over subset of variables in JuMP constraint

717 views Asked by At

I am trying to implement an arc-flow problem where I have a set of arcs in an array. Each arc is a custom data structure composed of from/to nodes. I want to add a constraint where I only include the arcs that go from a specific node (1), something like:

@constraint(m, sum(x[a] for a in arcs; a.from==1) == 1)

This does not work. What is the best approach to deal with this? Is there a way to do it without precomputing all outgoing arcs from each node first? If so, is there a way to add additional conditions? Thanks in advance

Bernardo

2

There are 2 answers

1
mlubin On BEST ANSWER

I'm guessing that the syntax you're looking for is

@constraint(m, sum(x[a] for a in arcs if a.from==1) == 1)

This follows from the standard Julia syntax for generator expressions.

However, the expression is just as inefficient as it would be in plain Julia because it loops through all arcs. If it this looping becomes a bottleneck, you'll need to reformulate the expression in another way, e.g., by precomputing the outgoing arcs from each node.

2
Przemyslaw Szufel On

You need to redefine your x to be an adjacency matrix, that is a square matrix that has 1 (or edge weight) where there is an arc between a pair of nodes and 0 otherwise.

Assuming that the set of vertices you are considering is N (e.g. N = 1:10 for 10 vertices) your constraint can now look like this:

@constraint(m, arcConstraint[n in N], sum(x[n,k] for k ∈ N) == 1 )

Note that arcConstraint is just the constraint name so you can reference it later.

The sum can be also written as sum(x[n,:]) if you actually know that you go through the entire column (depends on your exact scenario).