Julia - Continue outer loop - julia

I am currently porting an algorithm from Java to Julia and now I have come across a part where I have to continue an outer loop from an inner loop when some condition is met:
loopC: for(int x : Y){
for(int i: I){
if(some_condition(i)){
continue loopC;
}
}
}
I have found some issues on GitHub on this topic but there seems to be only a discussion about it and no solution yet. Does anybody know a way how to accomplish this in Julia?

As in some other languages julia uses break for this:
for i in 1:4
for j in 1:4
if j == 2
break
end
end
end
breaks out of the inner loop whenever j is 2
However, if you ever need to exit the outer loop you can use #goto and #label like so
for i in 1:4
for j in 1:4
if (j-i) == 2
#goto label1
end
if j == 2
#goto label2
end
do stuff
end
#label label2
end
#label label1
Straight from the julia docs http://docs.julialang.org/en/release-0.5/manual/control-flow/
It is sometimes convenient to terminate the repetition of a while
before the test condition is falsified or stop iterating in a for loop
before the end of the iterable object is reached. This can be
accomplished with the break keyword

As mentioned by #isebarn, break can be used to exit the inner loop:
for i in 1:3
for j in 1:3
if j == 2
break # continues with next i
end
#show (i,j)
end # next j
end # next i
(i, j) = (1, 1)
(i, j) = (2, 1)
(i, j) = (3, 1)
However, some caution is required because the behaviour of break depends on how the nested loops are specified:
for i in 1:3, j in 1:3
if j == 2
break # exits both loops
end
#show (i,j)
end # next i,j
(i, j) = (1, 1)
See https://en.wikibooks.org/wiki/Introducing_Julia/Controlling_the_flow#Nested_loops
It is also possible, albeit cumbersome, to return from a nested function that contains the inner loop:
for i in 1:3
(i -> for j in 1:3
if j == 2
return
end
#show (i,j)
end)(i)
end
(i, j) = (1, 1)
(i, j) = (2, 1)
(i, j) = (3, 1)

Related

Ways to scroll an index that takes on different values at another index in CPLEX

I have a problem in CPLEX: I have two index i and j. For each j, i is different.
When I write the constraints, how can I make it clear that for j=1, the index i goes from 1 to 10 while for j=2 the index i goes from 1 to 3 and for j=3 i goes from 1 to 7?
For example:
int num_j=...; range J=1..num_j;
int num_i=...; range I=1..num_i;
forall (i in I) // where in I there must be the different values for each J
forall (j in J)
constraint 1: sum(m in M) y[i][j][m] == 1;
At array variable indexer size - 3 ways : union , tuple set, decision expression within Making Optimization Simple
I gave 3 ways do deal with that challenge.
With your data
int num_j=3;
range J=1..num_j;
int num_i[J]=[10,3,7];
range M=1..1;
range I=1..max(j in J) num_i[j];
dvar boolean y[I][J][M];
subject to
{
forall (j in J)
forall (i in 1..num_i[j]) // where in I there must be the different values for each J
sum(m in M) y[i][j][m] == 1;
}
works fine

How to define a JuMP expression conditional on index value

I am trying to define a #NLexpression in JuMP that has different specifications at different indices. In the below example, I want the expression y[j,k] to be defined as 1/(x[j] - x[k]) when j != k and take some other value when j == k. I can simulate this behavior by defining an auxiliary variable z and adding constraints conditional on index values. Is there a similar way to define expression conditional on index values?
using JuMP, Ipopt
model = JuMP.Model(with_optimizer(Ipopt.Optimizer))
#variable(model, 0 <= x[1:2])
#NLexpression(model, y[j=1:2,k=1:2], 1/(x[j] - x[k])) # <- problematic line
#variable(model, z[1:2,1:2])
for j=1:2, k=1:2
if j == k
#constraint(model, z[j,k] == 1)
else
#NLconstraint(model, z[j,k] == 1/(p[j] - p[k]))
end
end
display(model)
You're not obligated to use JuMP's macros to create containers for expressions. You should be able to conditionally create the expressions as follows:
model = JuMP.Model()
#variable(model, 0 <= x[1:2])
y = Dict() # Or Array, if you prefer.
for j=1:2, k=1:2
if j == k
y[j,k] = 1
else
y[j,k] = #NLexpression(model, 1/(p[j] - p[k]))
end
end

JuMPDict change of dimension

I am using Julia 0.6.2 and JuMP 0.18.5 (I can't use a more recent version since I need to use an old package).
Creating JuMP variables with conditions on the index lead to a JuMPDict instead of an Array.
For example:
m = Model(solver = CplexSolver())
# type of x: JuMP.JuMPDict{JuMP.Variable,2}
#variable(m, x[i in 1:3, j in 1:3; i < j] >= 0)
# type of y: JuMP.JuMPDict{JuMP.Variable,3}
#variable(m, y[i in 1:3, j in 1:3, k in 1:3; i < j] >= 0)
I would like to apply a function f to x and to y[:, :, k] for all k in 1:3. However, I don't know how to define such a generic function.
I tried to set the argument type of f to JuMP.JuMPDict{JuMP.Variable,2}:
function f(input::JuMP.JuMPDict{JuMP.Variable,2})
...
end
I can use the function on x but not on y:
f(x) # Works
for k in 1:3
f(y[:, :, k]) # does not work as y is not an array
end
My last idea was to convert y into several JuMP.JuMPDict{JuMP.Variable,2}:
function convertTo2D(dict3D::JuMP.JuMPDict{JuMP.Variable,3}, k::Int)
dict2D = JuMP.JuMPDict{JuMP.Variable,2}() # This line returns "ERROR: KeyError: key :model not found"
for (key, value) in keys(dict3D)
if key[3] == k
dict2D[(key[1], key[2])] = value # Not sure if it will work
end
end
return dict2D
end
If this was working I could use:
for k in 1:3
f(convertTd2D(y, k))
end
Do you know how I could fix convertTo2D or do what I want another way?
Anonymous variables solved my problem. Thanks to them I can successively create the variables of y in a for loop. Variable y is now an array of "2D dictionaries" rather than a "3D dictionaries":
y = Array{JuMP.JuMPDict{JuMP.Variable,2}, 1}([])
for k in 1:3
yk = #variable(m, [i in 1:3, j in 1:3; i < j] >= 0)
f(yk)
push!(y, yk)
end

Dynamic programming problems using iteration

I have spent a lot of time to learn about implementing/visualizing dynamic programming problems using iteration but I find it very hard to understand, I can implement the same using recursion with memoization but it is slow when compared to iteration.
Can someone explain the same by a example of a hard problem or by using some basic concepts. Like the matrix chain multiplication, longest palindromic sub sequence and others. I can understand the recursion process and then memoize the overlapping sub problems for efficiency but I can't understand how to do the same using iteration.
Thanks!
Dynamic programming is all about solving the sub-problems in order to solve the bigger one. The difference between the recursive approach and the iterative approach is that the former is top-down, and the latter is bottom-up. In other words, using recursion, you start from the big problem you are trying to solve and chop it down to a bit smaller sub-problems, on which you repeat the process until you reach the sub-problem so small you can solve. This has an advantage that you only have to solve the sub-problems that are absolutely needed and using memoization to remember the results as you go. The bottom-up approach first solves all the sub-problems, using tabulation to remember the results. If we are not doing extra work of solving the sub-problems that are not needed, this is a better approach.
For a simpler example, let's look at the Fibonacci sequence. Say we'd like to compute F(101). When doing it recursively, we will start with our big problem - F(101). For that, we notice that we need to compute F(99) and F(100). Then, for F(99) we need F(97) and F(98). We continue until we reach the smallest solvable sub-problem, which is F(1), and memoize the results. When doing it iteratively, we start from the smallest sub-problem, F(1) and continue all the way up, keeping the results in a table (so essentially it's just a simple for loop from 1 to 101 in this case).
Let's take a look at the matrix chain multiplication problem, which you requested. We'll start with a naive recursive implementation, then recursive DP, and finally iterative DP. It's going to be implemented in a C/C++ soup, but you should be able to follow along even if you are not very familiar with them.
/* Solve the problem recursively (naive)
p - matrix dimensions
n - size of p
i..j - state (sub-problem): range of parenthesis */
int solve_rn(int p[], int n, int i, int j) {
// A matrix multiplied by itself needs no operations
if (i == j) return 0;
// A minimal solution for this sub-problem, we
// initialize it with the maximal possible value
int min = std::numeric_limits<int>::max();
// Recursively solve all the sub-problems
for (int k = i; k < j; ++k) {
int tmp = solve_rn(p, n, i, k) + solve_rn(p, n, k + 1, j) + p[i - 1] * p[k] * p[j];
if (tmp < min) min = tmp;
}
// Return solution for this sub-problem
return min;
}
To compute the result, we starts with the big problem:
solve_rn(p, n, 1, n - 1)
The key of DP is to remember all the solutions to the sub-problems instead of forgetting them, so we don't need to recompute them. It's trivial to make a few adjustments to the above code in order to achieve that:
/* Solve the problem recursively (DP)
p - matrix dimensions
n - size of p
i..j - state (sub-problem): range of parenthesis */
int solve_r(int p[], int n, int i, int j) {
/* We need to remember the results for state i..j.
This can be done in a matrix, which we call dp,
such that dp[i][j] is the best solution for the
state i..j. We initialize everything to 0 first.
static keyword here is just a C/C++ thing for keeping
the matrix between function calls, you can also either
make it global or pass it as a parameter each time.
MAXN is here too because the array size when doing it like
this has to be a constant in C/C++. I set it to 100 here.
But you can do it some other way if you don't like it. */
static int dp[MAXN][MAXN] = {{0}};
/* A matrix multiplied by itself has 0 operations, so we
can just return 0. Also, if we already computed the result
for this state, just return that. */
if (i == j) return 0;
else if (dp[i][j] != 0) return dp[i][j];
// A minimal solution for this sub-problem, we
// initialize it with the maximal possible value
dp[i][j] = std::numeric_limits<int>::max();
// Recursively solve all the sub-problems
for (int k = i; k < j; ++k) {
int tmp = solve_r(p, n, i, k) + solve_r(p, n, k + 1, j) + p[i - 1] * p[k] * p[j];
if (tmp < dp[i][j]) dp[i][j] = tmp;
}
// Return solution for this sub-problem
return dp[i][j];;
}
We start with the big problem as well:
solve_r(p, n, 1, n - 1)
Iterative solution is only to, well, iterate all the states, instead of starting from the top:
/* Solve the problem iteratively
p - matrix dimensions
n - size of p
We don't need to pass state, because we iterate the states. */
int solve_i(int p[], int n) {
// But we do need our table, just like before
static int dp[MAXN][MAXN];
// Multiplying a matrix by itself needs no operations
for (int i = 1; i < n; ++i)
dp[i][i] = 0;
// L represents the length of the chain. We go from smallest, to
// biggest. Made L capital to distinguish letter l from number 1
for (int L = 2; L < n; ++L) {
// This double loop goes through all the states in the current
// chain length.
for (int i = 1; i <= n - L + 1; ++i) {
int j = i + L - 1;
dp[i][j] = std::numeric_limits<int>::max();
for (int k = i; k <= j - 1; ++k) {
int tmp = dp[i][k] + dp[k+1][j] + p[i-1] * p[k] * p[j];
if (tmp < dp[i][j])
dp[i][j] = tmp;
}
}
}
// Return the result of the biggest problem
return dp[1][n-1];
}
To compute the result, just call it:
solve_i(p, n)
Explanation of the loop counters in the last example:
Let's say we need to optimize the multiplication of 4 matrices: A B C D. We are doing an iterative approach, so we will first compute the chains with the length of two: (A B) C D, A (B C) D, and A B (C D). And then chains of three: (A B C) D, and A (B C D). That is what L, i and j are for.
L represents the chain length, it goes from 2 to n - 1 (n is 4 in this case, so that is 3).
i and j represent the starting and ending position of the chain. In case L = 2, i goes from 1 to 3, and j goes from 2 to 4:
(A B) C D A (B C) D A B (C D)
^ ^ ^ ^ ^ ^
i j i j i j
In case L = 3, i goes from 1 to 2, and j goes from 3 to 4:
(A B C) D A (B C D)
^ ^ ^ ^
i j i j
So generally, i goes from 1 to n - L + 1, and j is i + L - 1.
Now, let's continue with the algorithm assuming that we are at the step where we have (A B C) D. We now need to take into account the sub-problems (which are already calculated): ((A B) C) D and (A (B C)) D. That is what k is for. It goes through all the positions between i and j and computes the sub problems.
I hope I helped.
The problem with recursion is the high number of stack frames that need to be pushed/popped. This can quickly become the bottle-neck.
The Fibonacci Series can be calculated with iterative DP or recursion with memoization. If we calculate F(100) in DP all we need is an array of length 100 e.g. int[100] and that's the guts of our used memory. We calculate all entries of the array pre-filling f[0] and f[1] as they are defined to be 1. and each value just depends on the previous two.
If we use a recursive solution we start at fib(100) and work down. Every method call from 100 down to 0 is pushed onto the stack, AND checked if it's memoized. These operations add up and iteration doesn't suffer from either of these. In iteration (bottom-up) we already know all of the previous answers are valid. The bigger impact is probably the stack frames; and given a larger input you may get a StackOverflowException for what was otherwise trivial with an iterative DP approach.

How to find the index of a set in Julia/JuMP?

I am trying to create a linear optimization model. I have a set that looks like this:
si=[1,51,39,400909,1244]
sj=[31,47,5]
The numbers in this set represent codes. I am trying to loop through the set to add a constraint to my model, but I do not want to loop through the sets using their values, I want to loop through the sets based on their indices.
Here is the code I have now:
si=[1,51,39,400909,1244]
sj=[31,47,5]
c= [3 5 2;
4 3 5;
4 5 3;
5 4 3;
3 5 4]
b= [80;
75;
80;
120;
60]
# x_ij >= 0 ∀ i = 1,...,5, j = 1,...,3
#defVar(m, x[i in si,j in sj] >= 0)
#setObjective(m,Min,sum{c[i,j]*x[i,j],i in si, j in sj})
# ∀j = 1,...,3
for j in sj
#addConstraint(m, sum{x[i,j],i in si} <= 480)
end
for i in si
#addConstraint(m, sum{x[i,j],j in sj} >= b[i])
end
I keep getting an error because the numbers in the sets are too big. Does anyone know how to loop through the indices instead? Or does anyone have another way to do this?
I am also having trouble printing my solution. Here is my code:
for i in n
for j in p
println("x",i,",",j,"= ", getValue(x[i,j]))
end
end (incorporating Iain Dunning's answer from below)
However the output only reads
Objective value: 1165.0
x5,3= 0.0
Do you know how to fix the output so I can read the values of my variables?
The code you have posted doesn't work because you are trying to index c by, e.g. 400909,47. Try this:
n = length(si)
p = length(sj)
#variable(m, x[i=1:n,j=1:p] >= 0)
#objective(m,Min,sum{c[i,j]*x[i,j],i=1:n,j=1:p})
for j in 1:p
#constraint(m, sum{x[i,j],i=1:n} <= 480)
end
for i in 1:n
#constraint(m, sum{x[i,j],j=1:p} >= b[i])
end

Resources