Iterating through a continuous decision variable and retrieving its values

Dear colleagues,

I am implementing a branch-and-check procedure in JuMP that requires to extract some variable values. For instance, I have to retrieve the values of decision variable X, that is defined as follows:

@variable(Master, 0 <= X[i in 1:m, j in 1:n+1, k in 1:n+1; j != k] <= 1)

After optimizing the Master model, this can be easily obtained:

XM = value.(Master[:X])

I pass XM as the argument of a function and i need to multiply its values by a certain amount :

function Master_Machine_Makespan(XM::JuMP.Containers.SparseAxisArray{Float64, 3, Tuple{Int64, Int64, Int64}},
    YM::Matrix{Float64}, m::Int8, n::Int16, p::Matrix{Int16}, s::Vector{Matrix{Int16}})
    #----- Calculate and return the makespan of each machine of the master problem

    rlx_Cmax = zeros(Float64, m)

    #----- Compute the sum of setup times of each machine

    for i in eachindex(XM)
        for j in eachindex(XM[i])
            for k in eachindex(XM[i][j])
                rlx_Cmax[i] += s[i][j, k] * XM[i][j][k]
            end
        end
    end

    return rlx_Cmax
end

If I use:

typeof(XM[i][j][k])

Julia returns me a variable of type Float64, however, I am getting the error message:
LoadError: ArgumentError: invalid index: (1, 1, 2) of type Tuple{Int64, Int64, Int64}

Anyone knows a way to fix this? I would really appreciate your help :slight_smile:

Without running your example it might be a bit hard to narrow down. From the error message I would maybe assume that

for i in eachindex(XM)

already iterates over all three dimensions of XM in form of tuples? could you maybe @show or println the I, maybe for completeness also j and k?

Similar question, are I,j,k in the typeof the same as in the for loops or indices you choose yourself? or in other words: What is typeof(XM)?

1 Like

After running:

    for i in eachindex(XM)
        for j in eachindex(XM[i])
            for k in eachindex(XM[i][j])
                println("i: $i, j: $j, k: $k")
            end
        end
    end

I get something like this:

i: (1, 1, 2), j: 1, k: 1
i: (1, 1, 3), j: 1, k: 1
i: (1, 1, 4), j: 1, k: 1
i: (1, 1, 5), j: 1, k: 1
i: (1, 1, 6), j: 1, k: 1
i: (1, 1, 7), j: 1, k: 1
i: (1, 2, 1), j: 1, k: 1
i: (1, 2, 3), j: 1, k: 1
i: (1, 2, 4), j: 1, k: 1 (…)

It seems that i refers to Tuple indices and, perhaps, I do not need j and k. Typeof(XM) returns:

JuMP.Containers.SparseAxisArray{Float64, 3, Tuple{Int64, Int64, Int64}}
1 Like

I would guess then XM[i...] should work fine for addressing that one and you can have j=i[2] and k=i[2]?

The type indicates XM is a 3-dimensional array and then ialready iterates over all enrties.

edit: ah I See, in your original code j,k are always just 1 anyways since XM[i] is a number already, and for k the [1] the j does is maybe ignored? Without running the code myself this is a bit Moree guesswork that actual debugging, but I hope that helps.

1 Like

It seems that SparseAxisArray in Julia should be iterated using eachindex(). The following loop worked fine:

    for (i, j, k) in eachindex(XM)
        rlx_Cmax[i] += s[i][j, k] * XM[i, j, k]
    end

Best wishes,

3 Likes