I am a full-time consultant and provide services related to the design, implementation and deployment of mathematical programming, optimization and data-science applications. I also teach courses and workshops. Usually I cannot blog about projects I am doing, but there are many technical notes I'd like to share. Not in the least so I have an easy way to search and find them again myself. You can reach me at erwin@amsterdamoptimization.com.

Friday, June 25, 2010

Ina project we encountered the problem where we loaded a GDX file and subsequently wanted to augment one of the sets in that GDX file with some elements. The following trick will do this:

set i(*); $gdxin data.gdx $load i * i has now elements a,b $onmulti set i /c/; $offmulti * i has now elements a,b,c parameter p(i) /a 1b 2c 3/; display i,p;

In the GDX file the set i has elements a and b. In the GAMS code we add the element c. This is not very intuitive, but it works. The advantage of this method is that we do this at compile time, i.e. we can declare parameters and variables over the set i. Note that we cannot use DISPLAY to debug this:

set i(*); $gdxin data.gdx $load i

display i;

$onmulti set i /c/; $offmulti

display i;

This code will show the same output for both display statements:

---- 5 SET i

a, b, c

---- 11 SET i

a, b, c

This is because the display statement is executed at execution time while the sets are formed at compile time.

The second model has only linear constraints so that may be preferable in general. The waiting time is handled implicitly in this model. I would probably make the model slightly larger by making this more explicit by introducing a positive variable wt(i):

time1(i).. t(i) - t(i-1) =e= d(i)/v(i) + wt(i);

The paper mentions that IPOPT solves these models in about .5 seconds, and suggest that a discretization yielding a shortest path problem is much faster. I would suggest to try also some other NLP solvers, as IPOPT is really geared towards large scale problems. Other solvers may be a lot faster than IPOPT on these small problems. Indeed with CONOPT I see:

The reported time is 0 seconds. (It is noted that the larger test problems in the paper are a little bit larger than this example, but not by much). Probably a good dense solver like DONLP will do very good on a model like this.

Thursday, June 10, 2010

When doing real applications the demands on writing reports are sometime very high. Users have special requirements how the reports look like, and they often allow very little deviation from what they want. For this reason I often use GDXXRW with the CLEAR/MERGE option to update a table with solution data. This option will allow us to maintain a carefully designed layout.

The following was a little bit of a puzzle. How to update the spreadsheet below while skipping column E (units). The data is 4 dimensional: Commodity, Variable, Region, Year.

With GDXXRW we cannot use MERGE as that will keep old values in the spreadsheet. The option CLEAR is also not usable as it will wipe out column E. Eventually I found the following to work:

Create an empty 5 dimensional parameter (rdim=4, cdim=1), so that we can CLEAR the body of the table

Then use the original 4 dimensional parameter (rdim=3, cdim=1) with a MERGE option to fill the table body.

May be it depends on whether some cells are empty or contain empty strings (the difference is not really visible in a spreadsheet).

However the same scheme for real rows would also be useful. E.g. in some cases I want data to be repeated, such as “YEAR”: in each row with such a key. just repeat the content.

Here I used the trick to introduce y2,y3,y5,… to make sure multiple year rows are being written. It would be better if GDXXRW would allow me to have multiple rows with row header “year”.

Update:

The “duplicate” errors are really warnings. The reason why some duplicate headers (“Production Detail”) don’t generate a message and others (“Yield”) do, depends on whether these descriptions are also used as UELS (set elements) in the GDX file.