examples/sorting.mod
changeset 1 c445c931472f
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/examples/sorting.mod	Mon Dec 06 13:09:21 2010 +0100
     1.3 @@ -0,0 +1,67 @@
     1.4 +/* sorting.mod - how to sort arrays in MathProg */
     1.5 +
     1.6 +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */
     1.7 +
     1.8 +#  Sometimes it is necessary to print parameters or variables in the
     1.9 +#  order of ascending or descending their values. Suppose, for example,
    1.10 +#  that we have the following subscripted parameter:
    1.11 +
    1.12 +set I := 1..12;
    1.13 +
    1.14 +param a{i in I} := Uniform(2, 7);
    1.15 +
    1.16 +#  If we print all its members:
    1.17 +
    1.18 +printf{i in I} "a[%d] = %g\n", i, a[i];
    1.19 +
    1.20 +#  the output may look like follows:
    1.21 +#
    1.22 +#  a[1]  = 2.64156
    1.23 +#  a[2]  = 2.04798
    1.24 +#  a[3]  = 2.14843
    1.25 +#  a[4]  = 4.76896
    1.26 +#  a[5]  = 6.09132
    1.27 +#  a[6]  = 3.27780
    1.28 +#  a[7]  = 4.06113
    1.29 +#  a[8]  = 4.05898
    1.30 +#  a[9]  = 6.63120
    1.31 +#  a[10] = 6.50318
    1.32 +#  a[11] = 3.46065
    1.33 +#  a[12] = 4.69845
    1.34 +#
    1.35 +#  However, we would like the parameter members to appear in the order
    1.36 +#  of ascending their values.
    1.37 +#
    1.38 +#  Introduce the following auxiliary parameter:
    1.39 +
    1.40 +param pos{i in I} :=
    1.41 +      1 + card({j in I: a[j] < a[i] or a[j] = a[i] and j < i});
    1.42 +
    1.43 +#  where pos[i] = k means that in the sorted list member a[i] would
    1.44 +#  have k-th position, 1 <= k <= |I|. Then introduce another auxiliary
    1.45 +#  parameter:
    1.46 +
    1.47 +param ind{k in 1..card(I)} := sum{i in I: pos[i] = k} i;
    1.48 +
    1.49 +#  where ind[k] = i iff pos[k] = i.
    1.50 +#
    1.51 +#  Now, the following statement:
    1.52 +
    1.53 +printf{k in 1..card(I)} "a[%d] = %g\n", ind[k], a[ind[k]];
    1.54 +
    1.55 +#  prints the parameter members in the desired order:
    1.56 +#
    1.57 +#  a[2]  = 2.04798
    1.58 +#  a[3]  = 2.14843
    1.59 +#  a[1]  = 2.64156
    1.60 +#  a[6]  = 3.27780
    1.61 +#  a[11] = 3.46065
    1.62 +#  a[8]  = 4.05898
    1.63 +#  a[7]  = 4.06113
    1.64 +#  a[12] = 4.69845
    1.65 +#  a[4]  = 4.76896
    1.66 +#  a[5]  = 6.09132
    1.67 +#  a[10] = 6.50318
    1.68 +#  a[9]  = 6.63120
    1.69 +
    1.70 +end;