alpar@1
|
1 |
/* sorting.mod - how to sort arrays in MathProg */
|
alpar@1
|
2 |
|
alpar@1
|
3 |
/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */
|
alpar@1
|
4 |
|
alpar@1
|
5 |
# Sometimes it is necessary to print parameters or variables in the
|
alpar@1
|
6 |
# order of ascending or descending their values. Suppose, for example,
|
alpar@1
|
7 |
# that we have the following subscripted parameter:
|
alpar@1
|
8 |
|
alpar@1
|
9 |
set I := 1..12;
|
alpar@1
|
10 |
|
alpar@1
|
11 |
param a{i in I} := Uniform(2, 7);
|
alpar@1
|
12 |
|
alpar@1
|
13 |
# If we print all its members:
|
alpar@1
|
14 |
|
alpar@1
|
15 |
printf{i in I} "a[%d] = %g\n", i, a[i];
|
alpar@1
|
16 |
|
alpar@1
|
17 |
# the output may look like follows:
|
alpar@1
|
18 |
#
|
alpar@1
|
19 |
# a[1] = 2.64156
|
alpar@1
|
20 |
# a[2] = 2.04798
|
alpar@1
|
21 |
# a[3] = 2.14843
|
alpar@1
|
22 |
# a[4] = 4.76896
|
alpar@1
|
23 |
# a[5] = 6.09132
|
alpar@1
|
24 |
# a[6] = 3.27780
|
alpar@1
|
25 |
# a[7] = 4.06113
|
alpar@1
|
26 |
# a[8] = 4.05898
|
alpar@1
|
27 |
# a[9] = 6.63120
|
alpar@1
|
28 |
# a[10] = 6.50318
|
alpar@1
|
29 |
# a[11] = 3.46065
|
alpar@1
|
30 |
# a[12] = 4.69845
|
alpar@1
|
31 |
#
|
alpar@1
|
32 |
# However, we would like the parameter members to appear in the order
|
alpar@1
|
33 |
# of ascending their values.
|
alpar@1
|
34 |
#
|
alpar@1
|
35 |
# Introduce the following auxiliary parameter:
|
alpar@1
|
36 |
|
alpar@1
|
37 |
param pos{i in I} :=
|
alpar@1
|
38 |
1 + card({j in I: a[j] < a[i] or a[j] = a[i] and j < i});
|
alpar@1
|
39 |
|
alpar@1
|
40 |
# where pos[i] = k means that in the sorted list member a[i] would
|
alpar@1
|
41 |
# have k-th position, 1 <= k <= |I|. Then introduce another auxiliary
|
alpar@1
|
42 |
# parameter:
|
alpar@1
|
43 |
|
alpar@1
|
44 |
param ind{k in 1..card(I)} := sum{i in I: pos[i] = k} i;
|
alpar@1
|
45 |
|
alpar@1
|
46 |
# where ind[k] = i iff pos[k] = i.
|
alpar@1
|
47 |
#
|
alpar@1
|
48 |
# Now, the following statement:
|
alpar@1
|
49 |
|
alpar@1
|
50 |
printf{k in 1..card(I)} "a[%d] = %g\n", ind[k], a[ind[k]];
|
alpar@1
|
51 |
|
alpar@1
|
52 |
# prints the parameter members in the desired order:
|
alpar@1
|
53 |
#
|
alpar@1
|
54 |
# a[2] = 2.04798
|
alpar@1
|
55 |
# a[3] = 2.14843
|
alpar@1
|
56 |
# a[1] = 2.64156
|
alpar@1
|
57 |
# a[6] = 3.27780
|
alpar@1
|
58 |
# a[11] = 3.46065
|
alpar@1
|
59 |
# a[8] = 4.05898
|
alpar@1
|
60 |
# a[7] = 4.06113
|
alpar@1
|
61 |
# a[12] = 4.69845
|
alpar@1
|
62 |
# a[4] = 4.76896
|
alpar@1
|
63 |
# a[5] = 6.09132
|
alpar@1
|
64 |
# a[10] = 6.50318
|
alpar@1
|
65 |
# a[9] = 6.63120
|
alpar@1
|
66 |
|
alpar@1
|
67 |
end;
|