Lindo Systems

MODEL:
! Linear ordering of objects or products,
   based on pairwise comparisons(LINERORD);
! Keywords: Linear Ordering / Sorting / Matching;
SETS:
 PROD: RANK; ! Each product will get a rank;
 PXP( PROD, PROD): C;
ENDSETS
DATA:
 PROD = KONIG, FURST, PILSURQ, GUNZB, RIEGELE,
        PAULA, JEVER, BECKS,   WARST, BUD;
! Some data on German beverages;
 C= ! Times that object I was preferred over J;
0    2    2    3    3    5    5    5    4    4
4    0    3    3    4    3    2    3    2    2
4    3    0    3    5    4    3    2    4    4
3    3    3    0    5    6    3    4    4    3
3    2    1    1    0    1    4    4    5    3
1    3    2    0    5    0    5    4    1    4
1    4    3    3    2    1    0    2    1    3
1    3    4    2    2    2    4    0    4    2
2    4    2    2    1    5    5    2    0    4
2    4    2    3    3    2    3    4    2    0;
ENDDATA
!---------------------------------------------;
SETS:
PIP( PROD, PROD)| &1 #LT# &2:
   X; ! X(I,J) = 1 if I precedes J in our ranking; 
PIPIP( PROD, PROD, PROD)
            | &1 #LT# &2 #AND# &2 #LT# &3: S;
ENDSETS

! Maximize the number of times our pairwise
  ordering matches that of our testers;
MAX =
@SUM( PIP( I, J): C( I, J) * X( I, J)
      + C( J, I) *(1 - X( I, J)));

! The rankings must be transitive, that is,
  If I->J and J->K, then I->K;
@FOR( PIPIP( I, J, K): 
!   Note N*(N-1)*(N-2)/6 of these!;
X( I, J) + X ( J, K) - X( I, K) 
                     + S( I, J, K) = 1;
    @BND( 0, S( I, J, K), 1);
   );

! Make X's 0 or 1;
@FOR( PIP: @BIN( X););

! Count number products before product I( + 1);
@FOR( PROD( I):
 RANK( I) = 1 + @SUM( PIP( K, I): X( K, I))
              + @SUM( PIP( I, K): 1 - X( I, K));
   ); 
END