Algorithm Alley by Andrew Colin Listing One /* FILE: ahp.c ** AUTHOR: Andrew Colin ** DATE: 29th October 1998 ** DISCLAIMER: No liability is assumed by the author for any use made ** of this program. ** DISTRIBUTION: Any use may be made of this program, as long as the ** clear acknowledgment is made to the author in code and runtime ** executables. The author retains copyright. */ #include #include #include #include #include #define MAX_ATTRIBUTES 10 #define N_CASES 3 #define MAX_ITERATIONS 100 #define randomize() srand((unsigned)time(NULL)) typedef struct element { int n_factors; /* Number of attributes/items */ char attributes[MAX_ATTRIBUTES][0xFF]; /* Not used */ double preferences[MAX_ATTRIBUTES][MAX_ATTRIBUTES]; /* rankings */ struct element *branch[MAX_ATTRIBUTES]; /* Address of sub-attribute */ double eigenvector[MAX_ATTRIBUTES]; /* computed rankings */ double ranking[N_CASES]; /* Final, relative worth of each choice */ } ELEMENT; ELEMENT array[] = { { 4, {"Top-level", "b", "c", "d"}, {{1,1.5,0.75,3},{0.667,1,0.5,2},{1.333,2,1,4},{0.333,0.5,0.25,1}}, {&array[1], &array[2], &array[3], &array[4]} }, { 3,{"Documentation"},{{1,0.25,0.333},{4,1,1.333},{3,0.75,1}}, {NULL}}, { 3, {"Cost"}, {{1,1.6,4},{0.625,1,2.5},{0.25,0.4,1}}, { NULL } }, { 3, {"IDE"}, {{1,0.714,1.25},{1.4,1,1.75},{0.8,0.571,1}}, { NULL } }, { 2, {"C++ features"}, {{1,2},{0.5,1}}, { &array[5], &array[6] } }, { 3, {"STL library"}, {{1,0.111,0.111},{9,1,1},{9,1,1}}, { NULL } }, { 3, {"Exception handling"}, {{1,1,9},{1,1,9},{0.111,0.111,1}},{NULL}}, }; /*---------------------------------------------------------------------------*/ /* Multiplies a matrix m and a vector v; returns the result in vector * r. Note the syntax for passing a statically declared multidimensional array * to a function (see K&R, p112, second edition) */ void mmult( int size, double m[][MAX_ATTRIBUTES], double v[], double r[] ) { int i, j; for (i=0; i largest) largest = s; } /* Normalise by dividing by element of largest absolute magnitude */ for (i=0; in_factors, e->preferences, e->eigenvector ); } /*---------------------------------------------------------------------------*/ /* Recursive routine to evaluate the ranking vector for an element of * a hierarchy, where the priorities (or principal eigenvectors) have * already been calculated. */ void evaluate_hierarchy( ELEMENT *e ) { int i, j; if (e->branch[0] == NULL) { /* At bottom level of hierarchy */ assert (e->n_factors == N_CASES); for (i=0; iranking[i] = e->eigenvector[i]; } else { for (i=0; in_factors; i++) /* At intermediate level */ evaluate_hierarchy( e->branch[i] ); for (j=0; jranking[j] = 0.0; for (i=0; in_factors; i++) e->ranking[j] += e->eigenvector[i] * e->branch[i]->ranking[j]; } } #ifdef _DEBUG for (i=0; iranking[i]); #endif } /*---------------------------------------------------------------------------*/ main() { int i; randomize(); printf("\nWelcome to the Analytic Hierarchy Process!"); printf("\nLast compiled on %s, %s\n", __TIME__, __DATE__); /* Evaluate priority arrays for each element in 'array' */ for (i=0; i