Forum Discussion

FICO's avatar
FICO
Community Manager
6 years ago

Naming sets where the elements are a combination of indices

Hello,

I have a follow-up question on the MOSEL best practices described here, regarding naming sets:

https://www.fico.com/fico-xpress-optimization/docs/latest/mosel/UG/dhtml/moselugapp_sec_secappname.html

The example explains how it is recommended to calculate ISODD just once and then to use this instead of calculating the intermediate set several times. This makes a lot of sense, and I was wondering how you would extend this best practice if you are cycling through multiple sets.

e.g. if we have an array with 3 indices i,j and k and at several places in the model, we want to execute operations only for those i,j,k's where some condition f(i,j,k)= TRUE. Is there a way to define a set where each element is a valid combination of indices?

Thanks for your help,

Ingrid

3 Replies

  • FICO's avatar
    FICO
    Community Manager

    A collection of index tuples for which a condition evaluates to 'true' is usually best represented via a sparse multidimensional array of Booleans in Mosel, see for example https://examples.xpress.fico.com/example.pl?id=loopproj

    So an extension to several dimensions of the example from the Mosel User Guide that you are referring to could be:

    declarations
     I,J,K: range
     Cond: dynamic array(I,J,K) of boolean
    end-declarations
     
    ! Index tuples for which the condition holds
    forall(i in I, j in J, k in K | isodd(i) and j<>k and (k mod 7 = 0)) Cond(i,j,k)
     
    ! Use the precalculated condition
    forall(i in I, j in J, k in K | exists(Cond(i,j,k)) ) x(i,j,k) is_integer
    ...
    sum(i in I, j in J, k in K | exists(Cond(i,j,k))) x(i,j,k) >= 10
  • FICO's avatar
    FICO
    Community Manager

    Very clear. Thank you. The examples in the link you shared are interesting as well. As a follow-up question to the example in proj.mos: I understand the difference in the enumeration results in the 4 loops demonstrated. If you use exists, then the difference is that "range" will return ordered tuples, while "set of integer" will report them in the order they appear. So should I expect that "set of integer" will be faster because there is no sorting? Is the difference noticeable? Which is recommended for indexing integers: range or set of integer? Thanks for your perspective.

  • FICO's avatar
    FICO
    Community Manager

    In general a 'range' index set can be expected to be faster than 'set of integer', so wherever this form makes sense we recommend to use 'range' in preference over 'set of integer'.

    Differences in speed may only become measurable with quite large data sets. However, there is a difference regarding memory use for storing the set itself: a range is defined by its first and last value whereas for general sets all individual set elements need to be stored.