How to create multidimensional sets in JuMP/Julia as in GAMS

In GAMS, we can create multidimensional sets as follows

Set i       "mining regions"     / china, ghana, ee+ussr, s-leone /
    n       "ports"              / accra, freetown, leningrad, shanghai /
    in(i,n) "mines to ports map" / china  .shanghai
                                   ghana  .accra
                                   ee+ussr.leningrad
                                   s-leone.freetown /;

How can I do the same in JuMP/Julia?

1 Like

Usually I’d suggest a vector of symbols, but since your regions contain characters like + and - probably a vector of strings is better in your case. Then the mines to ports map could be a dictionary, like so:

regions = ["china", "ghana", "ee+ussr", "s-leone"]
ports = ["accra", "freetown", "leningrad", "shanghai"]
links = Dict("china"  => "shanghai",
             "ghana" => "accra",
             "ee+ussr" => "leningrad",
             "s-leone" => "freetown")

I teach an introductory course in energy system LP modeling. The first assignment is to build (or rather modify) a very simple model of a district heating system. The model was originally written in GAMS but I recently converted it to Julia/JuMP - you might find it useful to see how things can translate. Both versions (and the assignment itself) are available here:

4 Likes

When I index it in a constraint, I obtain a key error.

Is it not better to have it as a vector of symbols?

It’s very hard to say without seeing the error in context, but key error means you’re trying to look up an element in the dictionary that doesn’t exist. Wild guess: are you doing something like links[x] where x is an integer?

julia> links["china"]
"shanghai"

julia> links[23]
ERROR: KeyError: key 23 not found
julia> using JuMP

julia> regions = ["china", "ghana", "ee+ussr", "s-leone"]
4-element Array{String,1}:
 "china"
 "ghana"
 "ee+ussr"
 "s-leone"

julia> ports = ["accra", "freetown", "leningrad", "shanghai"]
4-element Array{String,1}:
 "accra"
 "freetown"
 "leningrad"
 "shanghai"

julia> links = [
           "china"  => "shanghai",
           "ghana" => "accra",
           "ee+ussr" => "leningrad",
           "s-leone" => "freetown"
       ]
4-element Array{Pair{String,String},1}:
   "china" => "shanghai"
   "ghana" => "accra"
 "ee+ussr" => "leningrad"
 "s-leone" => "freetown"

julia> model = Model()
A JuMP Model
Feasibility problem with:
Variables: 0
Model mode: AUTOMATIC
CachingOptimizer state: NO_OPTIMIZER
Solver name: No optimizer attached.

julia> @variable(model, arcs[r=regions, p=ports; (r => p) in links])
JuMP.Containers.SparseAxisArray{VariableRef,2,Tuple{String,String}} with 4 entries:
  [s-leone, freetown ]  =  arcs[s-leone,freetown]
  [china, shanghai   ]  =  arcs[china,shanghai]
  [ee+ussr, leningrad]  =  arcs[ee+ussr,leningrad]
  [ghana, accra      ]  =  arcs[ghana,accra]

julia> arcs["s-leone", "freetown"]
arcs[s-leone,freetown]
2 Likes

See also this implementation in JuMP of the classical transport problem in GAMS:

3 Likes