! 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; 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