Is the "set" conept in the roadmap (or is it not needed at all..)?


#1

Hello,
is the implementation of the “set” concept, as known in ampl/gams languages, somewhere in the roadmap of JuMP development, or do you believe that the core Julia indexing is enought and there is no need for it ?

I had a look at the transport.jl example, but honestly using “core” indexing seems to add more symbols and is less readable than if the model could have “natively” written using sets.

Only as an example, Pyomo [http://www.pyomo.org], a similar optimisation-related library for python, does implement a “set” concept, altought python has very nice indexing capabilities too…

Is there some doc that make a comparation on how models would have been written using set, and how to write them using julia indexing?


#2

Personally, I find the native collections and comprehensions to be pretty clean.


#3

I agree. Most of the JuMP example models are not coded in a way that appeals to experienced modelers, especially AMPL users who are accustomed to clean syntax.

But clean syntax using “sets” is quite possible in JuMP right now. To teach myself JuMP last week, I rewrote the multi.jl model to be as close to AMPL syntax as possible. The trick is to use “dictionaries of tuples” for parameters and variables instead of arrays (matrices). Here is the JuMPy part of my modified model:

    # index sets
    orig = [:GARY, :CLEV, :PITT]
    dest = [:FRA, :DET, :LAN, :WIN, :STL, :FRE, :LAF]
    prod = [:bands, :coils, :plate]

    @variables multi begin
        Trans[p in prod, o in orig, d in dest] >= 0
    end

    @constraints multi begin
        c_supply[p in prod, o in orig],
            sum(Trans[p,o,d] for d in dest) == supply[p,o]

        c_demand[p in prod, d in dest],
            sum(Trans[p,o,d] for o in orig) == demand[p,d]

        c_total_shipment[o in orig, d in dest],
            sum(Trans[p,o,d] for p in prod) - limit[o,d] <= 0
    end

    @objective multi Max begin
        sum(cost[p,o,d] * Trans[p,o,d] for p in prod, o in orig, d in dest)
    end

I uploaded the complete model here. In addition to using dictionaries of tuples, I chose to use arrays of symbols instead of arrays of strings to represent the indexing sets. I also read input data directly into dataframes using the wsv"""...""" syntax.

I think this approach is significantly more readable than the original version. It is also more fault tolerant. The original model does a 3-dimensional reshape of the cost data, which is very easy to mess up. This is not needed when dictionaries are indexed by name in the equations.

But most importantly: when you use numerical indexes of multidimensional parameters and variables (as the original model does), a simple typo can cause your model to fail silently. If line 87 of the original model has been written cost[j,p,i] instead of cost[j,i,p] the model would solve and produce a reasonable looking but completely incorrect result. (No errors are produced because the orig and prod sets both have three elements.)


#4

The JuMP example models are not comprehensive and are not meant to promote one modeling style over another. We’re happy to take contributions, either as PRs to JuMP or as notebook submissions to juliaopt-notebooks.


#5

Yeah, sorry if I came across as a bit harsh in my post. I think you guys have done an amazing job with JuMP. But honesty, when I looked through the example models I thought: “there is NO WAY I’m going to write large complex models using numerical indexes - wasn’t this supposed to be nicer than Matlab?” The repeated @constraint macros with parentheses were pretty ugly too. I nearly abandoned the Julia/JuMP notion on the spot, but luckily I decided to learn some Julia anyway. Within an hour or two I realized that JuMP models can be written more cleanly. And when I finished the example above I was very happy with the result. Now if I can only convince my colleagues to abandon GAMS … :slight_smile:


#6

@NickNack thanks, I agree with you and feel dictionary-based indexing vs position-based one much more “natural”. Now I could also agree with @ccoffrin :slight_smile:

Following your approach, I rewritten the transport.gms GAMS problem in JuMP… I think it could be useful for those coming from GAMS, as the transport problem is the case-study in the GAMS tutorial and all GAMS users are familiar with it…


#7

Nice writeup, I wish I had something like that to peek at last week when I started playing with Julia/JuMP. However, I am now leaning towards using Named Arrays instead of Dicts for model parameters and variables. I posted some benchmarks here and found that Named Arrays performed significantly better. Dicts are probably fast enough though in most cases unless your optimization model is huge. But since I also build simulation models which do a lot of iterated assignments I wanted the extra speed.