Lindo Systems

! Analytic Hierarchy Process Example;
!   Given a set of items, and a
  set of criteria on which to evaluate the items,
  find the best item.
    A key idea is to convert pairwise comparisons
 into complete ordered comparisons;

! Ref: Saaty, T. (1990) "How to make a decision: The Analytic Hierarchy Process,"
European Journal of Operational Research 48:9-26.;
! Keywords: AHP, Analytic hierarchy process, Eigenvalue, Multi-criteria, Saaty;
sets:
  criterion : eigenval, wgt;
  item: ieigenval, totscore;
  cxc( criterion, criterion): r, eigenvec;
  ixi( item, item) : rtmp, eigenvectmp;
  ixc( item, criterion): cscore;
  cxixi( criterion, item, item): ritem;
endsets
data:
!  Example from Saaty;
! Data for choosing which of three houses to buy. There are 8 criteria:
   size of house, closeness to transportation, neighborhood, age,
   backyard quality, modernity, condition, and financing;
  criterion= size    trans     hood   age  yard    modern   condn  finance;
!   Pairwise comparison of the importance of the criteria.
     r( j, k) > 1 implies j is more important than k, e.g., r( 1, 2) = 5
    means size is more important than trans. Also, r( j, k) = 1/ r( k, j) ;
     r =       1      5        3       7     6       6    0.33333 0.25
              0.2     1       0.33333  5     3       3    0.2     0.14286
              0.33333 3       1        6     3       4      6     0.2
              0.14286 0.2     0.16667  1    0.33333 0.25  0.14286 0.125
              0.16667 0.33333 0.33333  3     1      0.5   0.2     0.16667
              0.16667 0.33333 0.25     4     2       1    0.2     0.16667
                3     5       0.16667  7     5       5     1      0.5
                4     7        5       8     6       6     2       1
;
! The items among which we are choosing;
   item = HOUSEA HOUSEB HOUSEC;
! The goodness of each alternative on each criterion. Again,
  ritem( i, j) > 1 means item i is better than item j on this criterion, e.g.,
  ritem( 2, 3, 2) = 8 means on the trans criterion, HOUSEC is better than HOUSEB ;
  ritem =  1      6     8  ! size;
         0.16667  1     4
         0.125   0.25   1

           1      7    0.2 ! trans;
        0.14286   1   0.125
           5      8     1

           1      8     6  !Hood;
        0.125     1   0.25
        0.16667   4     1  

           1      1     1  ! Age;
           1      1     1
           1      1     1   

           1      5     4  ! yard;
          0.2     1  0.33333
          0.25    3     1  

           1      8  6     ! modern;
         0.125    1  0.2
         0.16667  5  1  
           1     0.5   0.5 ! Condn;
           2      1     1
           2      1     1  

           1  0.14286  0.2 ! Finance;
           7      1     3
           5  0.33333   1 
  ;
enddata

calc:
  @SET( 'TERSEO',2);   ! Output level (0:verb, 1:terse, 2:only errors, 3:none);
!  Process he criteria;! finance;
    eigenval, eigenvec = @EIGEN( r);
! Scale the eigen vectors;
! Get the index, icmx of the largest eigenvalue;
     kcmx = 1;
     evalmx = eigenval( 1);
     @for( criterion( k):
       @ifc( eigenval( k) #gt# evalmx:
          kcmx = k;
          evalmx = ieigenval( k);
           );
         ); 
!    @write( 'Largest eigenval= ', evalmx, @newline( 1));
! Scale the corresponding eigenvector; 
    tot = @sum( criterion( k): eigenvec( k, kcmx));
    @for( criterion( k):
       eigenvec( k, kcmx) = eigenvec( k, kcmx) / tot;
!       @write( criterion( k),' ', eigenvec( k, kcmx), @newline( 1));
       wgt( k) = eigenvec( k, kcmx);
        );

 ! Process the alternatives, by criteria;
  @for( criterion( k):
!    @write(' For criterion ', criterion( k), @newline( 1));
    @for( ixi( i, j):
       rtmp( i, j) = ritem( k, i, j);
        );
      ieigenval, eigenvectmp = @eigen( rtmp);

! Get the index, imx of the largest eigenvalue;
     imx = 1;
     evalmx = ieigenval( 1);
     @for( item( i):
       @ifc( ieigenval( i) #gt# evalmx:
          imx = i;
          evalmx = ieigenval( i);
           );
  !      @write( i, ' ieigenval= ', ieigenval( i), @newline( 1));
         ); 
!    @write( 'Largest eigenval= ', evalmx, @newline( 1));

! Scale the eigen vector having the largest eigenval;
    tot = @sum( item( i): eigenvectmp( i, imx));
!    @write( criterion( k), ': tot= ', tot, @newline( 1));
    @for( item( i):
       eigenvectmp( i, imx) = eigenvectmp( i, imx) / tot;
!      @write( i, '  ', eigenvectmp(i, imx), @newline( 1));
! Fill in the cscore( i, k) of how item i scores on criterion k;
      cscore( i, k) = eigenvectmp( i, imx);
       );
 );

! Compute the final score for each item;
 @for( item( i):
   totscore( i) = @sum( criterion( k): eigenvec( k, kcmx) * cscore( i, k));
     );

! Write a little report;
@write('     Analytic Hierarchy Process Applied to Choosing an Alternative',
    @newline( 1));
@write('         ');
@for( criterion( k):
  @write( @format( criterion( k), '8s'));
    );
@write( '   Total',  @newline( 1));
@write('     Wgt=');
@for( criterion( k):
   @write( @format( wgt( k), '8.3f'));
    );
@write( @newline( 1));
@for( item( i):
  @write( @format( item( i), '8s'),':');
@for( criterion( k):
   @write( @format( cscore( i, k), '8.3f'));
    );
   @write( @format( totscore( i), '8.3f'));
@write( @newline( 1));
    );
@write( @newline( 1));
 
endcalc