Marthio
Marthio

Reputation: 11

Saving multiple sparse arrays in one big sparse array

I have been trying to implement some code in Julia JuMP. The idea of my code is that I have a for loop inside my while loop that runs S times. In each of these loops I solve a subproblem and get some variables as well as opt=1 if the subproblem was optimal or opt=0 if it was not optimal. Depending on the value of opt, I have two types of constraints, either optimality cuts (if opt=1) or feasibility cuts (if opt=0). So the intention with my code is that I only add all of the optimality cuts if there are no feasibility cuts for s=1:S (i.e. we get opt=1 in every iteration from 1:S). What I am looking for is a better way to save the values of ubar, vbar and wbar. Currently I am saving them one at a time with the for-loop, which is quite expensive. So the problem is that my values of ubar,vbar and wbar are sparse axis arrays. I have tried to save them in other ways like making a 3d sparse axis array, which I could not get to work, since I couldn't figure out how to initialize it.

The below code works (with the correct code inserted inside my <>'s of course), but does not perform as well as I wish. So if there is some way to save the values of 2d sparse axis arrays more efficiently, I would love to know it! Thank you in advance!

ubar2=zeros(nV,nV,S)
vbar2=zeros(nV,nV,S)
wbar2=zeros(nV,nV,S)
while <some condition>
    opts=0
    for s=1:S
        <solve a subproblem, get new ubar,vbar,wbar and opt=1 if optimal or 0 if not>
        opts+=opt
        if opt==1
            # Add opt cut Constraints
            for i=1:nV
                for k=1:nV
                    if i!=k
                        ubar2[i,k,s]=ubar[i,k]
                    end
                end
                for j=i:nV
                    if links[i,j]==1
                        vbar2[i,j,s]=vbar[i,j]
                        wbar2[i,j,s]=wbar[i,j]
                    end
                end
            end
        else
            # Add feas cut Constraints
            @constraint(mas, <constraint from ubar,vbar,wbar> <= 0)
            break
        end
        if opts==S
            for s=1:S
               @constraint(mas, <constraint from ubar2,vbar2,wbar2> <= <some variable>)
            end
        end
    end

Upvotes: 1

Views: 196

Answers (1)

Beno&#238;t Legat
Beno&#238;t Legat

Reputation: 968

A SparseAxisArray is simply a thin wrapper in top of a Dict. It was defined such that when the user creates a container in a JuMP macro, whether he gets an Array, a DenseAxisArray or a SparseAxisArray, it behaves as close as possible to one another hence the user does not need to care about what he obtained for most operations. For this reason we could not just create a Dict as it behaves differently as an array. For instance you cannot do getindex with multiple indices as x[2, 2]. Here you can use either a Dict or a SparseAxisArray, as you prefer. Both of them have O(1) complexity for setting and getting new elements and a sparse storage which seems to be adequate for what you need. If you choose SparseAxisArray, you can initialize it with

ubar2 = JuMP.Containers.SparseAxisArray(Dict{Tuple{Int,Int,Int},Float64}())

and set it with

ubar2[i,k,s]=ubar[i,k]

If you choose Dict, you can initialize it with

ubar2 = Dict{Tuple{Int,Int,Int},Float64}()

and set it with

ubar2[(i,k,s)]=ubar[i,k]

Upvotes: 1

Related Questions