Naming sets
It is customary in mathematical models to write index sets as 1,...,N or the like. Instead of translating this directly into Mosel code like the following:
declarations x: array(1..N) of mpvar end-declarations sum(i in 1..N) x(i) >= 10
it is recommended to name index sets:
declarations RI = 1..N x: array(RI) of mpvar end-declarations sum(i in RI) x(i) >= 10
The same remark holds if several loops or operators use the same intermediate set(s). Instead of
forall(i in RI | isodd(i)) x(i) is_integer forall(i in RI | isodd(i)) x(i) <= 5 sum(i in RI | isodd(i)) x(i) >= 10
which calculates the same intermediate set of odd numbers three times, it is more efficient to define this set explicitly and calculate it only once:
ODD:= union(i in RI | isodd(i)) {i} forall(i in ODD) x(i) is_integer forall(i in ODD) x(i) <= 5 sum(i in ODD) x(i) >= 10
Alternatively, loops of the same type and with the same index set(s) may be regrouped to reduce the number of times that the sets are calculated:
forall(i in RI | isodd(i)) do x(i) is_integer x(i) <= 5 end-do sum(i in RI | isodd(i)) x(i) >= 10