alpar@1: /* sorting.mod - how to sort arrays in MathProg */ alpar@1: alpar@1: /* Written in GNU MathProg by Andrew Makhorin */ alpar@1: alpar@1: # Sometimes it is necessary to print parameters or variables in the alpar@1: # order of ascending or descending their values. Suppose, for example, alpar@1: # that we have the following subscripted parameter: alpar@1: alpar@1: set I := 1..12; alpar@1: alpar@1: param a{i in I} := Uniform(2, 7); alpar@1: alpar@1: # If we print all its members: alpar@1: alpar@1: printf{i in I} "a[%d] = %g\n", i, a[i]; alpar@1: alpar@1: # the output may look like follows: alpar@1: # alpar@1: # a[1] = 2.64156 alpar@1: # a[2] = 2.04798 alpar@1: # a[3] = 2.14843 alpar@1: # a[4] = 4.76896 alpar@1: # a[5] = 6.09132 alpar@1: # a[6] = 3.27780 alpar@1: # a[7] = 4.06113 alpar@1: # a[8] = 4.05898 alpar@1: # a[9] = 6.63120 alpar@1: # a[10] = 6.50318 alpar@1: # a[11] = 3.46065 alpar@1: # a[12] = 4.69845 alpar@1: # alpar@1: # However, we would like the parameter members to appear in the order alpar@1: # of ascending their values. alpar@1: # alpar@1: # Introduce the following auxiliary parameter: alpar@1: alpar@1: param pos{i in I} := alpar@1: 1 + card({j in I: a[j] < a[i] or a[j] = a[i] and j < i}); alpar@1: alpar@1: # where pos[i] = k means that in the sorted list member a[i] would alpar@1: # have k-th position, 1 <= k <= |I|. Then introduce another auxiliary alpar@1: # parameter: alpar@1: alpar@1: param ind{k in 1..card(I)} := sum{i in I: pos[i] = k} i; alpar@1: alpar@1: # where ind[k] = i iff pos[k] = i. alpar@1: # alpar@1: # Now, the following statement: alpar@1: alpar@1: printf{k in 1..card(I)} "a[%d] = %g\n", ind[k], a[ind[k]]; alpar@1: alpar@1: # prints the parameter members in the desired order: alpar@1: # alpar@1: # a[2] = 2.04798 alpar@1: # a[3] = 2.14843 alpar@1: # a[1] = 2.64156 alpar@1: # a[6] = 3.27780 alpar@1: # a[11] = 3.46065 alpar@1: # a[8] = 4.05898 alpar@1: # a[7] = 4.06113 alpar@1: # a[12] = 4.69845 alpar@1: # a[4] = 4.76896 alpar@1: # a[5] = 6.09132 alpar@1: # a[10] = 6.50318 alpar@1: # a[9] = 6.63120 alpar@1: alpar@1: end;