#include #include #include #include #include #include #include #include #include "cleanbench.h" #include "randnum.h" /************************* ** ASSIGNMENT ALGORITHM ** *************************/ /* ** DEFINES */ #define ASSIGNROWS 101L #define ASSIGNCOLS 101L /* ** TYPEDEFS */ typedef struct { union { long *p; long (*ap)[ASSIGNROWS][ASSIGNCOLS]; } ptrs; } longptr; /* ** PROTOTYPES */ static clock_t DoAssignIteration(long *array, unsigned long num_arrays); static void LoadAssignArrayWithRand(long *array, unsigned long num_arrays); static void LoadAssign(long array[][ASSIGNCOLS]); static void CopyToAssign(long arrayfrom[][ASSIGNCOLS], long arrayto[][ASSIGNCOLS]); static void Assignment(long array[][ASSIGNCOLS]); static void calc_minimum_costs(long tableau[][ASSIGNCOLS]); static int first_assignments(long tableau[][ASSIGNCOLS], short assignedtableau[][ASSIGNCOLS]); static void second_assignments(long tableau[][ASSIGNCOLS], short assignedtableau[][ASSIGNCOLS]); /************* ** DoAssign ** ************** ** Perform an assignment algorithm. ** The algorithm was adapted from the step by step guide found ** in "Quantitative Decision Making for Business" (Gordon, ** Pressman, and Cohn; Prentice-Hall) ** ** ** NOTES: ** 1. Even though the algorithm distinguishes between ** ASSIGNROWS and ASSIGNCOLS, as though the two might ** be different, it does presume a square matrix. ** I.E., ASSIGNROWS and ASSIGNCOLS must be the same. ** This makes for some algorithmically-correct but ** probably non-optimal constructs. ** */ double DoAssign(void) { long* array = NULL; clock_t total_time = 0; int iterations = 0; static int num_arrays = 0; static bool is_adjusted = false; if (is_adjusted == false) { is_adjusted = true; /* ** Self-is_adjustedment code. The system begins by working on 1 ** array. If it does that in no time, then two arrays ** are built. This process continues until ** enough arrays are built to handle the tolerance. */ do { ++num_arrays; array = realloc(array, sizeof(long) * ASSIGNROWS * ASSIGNCOLS * num_arrays); /* ** Do an iteration of the assignment alg. If the ** elapsed time is less than or equal to the permitted ** minimum, then allocate for more arrays and ** try again. */ } while (DoAssignIteration(array, num_arrays) <= MINIMUM_TICKS); } else { array = malloc(sizeof(long) * ASSIGNROWS * ASSIGNCOLS * num_arrays); } do { total_time += DoAssignIteration(array, num_arrays); ++iterations; } while (total_time < MINIMUM_SECONDS * CLOCKS_PER_SEC); free(array); return (double)(iterations * CLOCKS_PER_SEC *num_arrays) / (double)total_time; } /********************** ** DoAssignIteration ** *********************** ** This routine executes one iteration of the assignment test. ** It returns the number of ticks elapsed in the iteration. */ static clock_t DoAssignIteration(long *array, unsigned long num_arrays) { clock_t start, stop; longptr abase; unsigned long i; abase.ptrs.p=array; LoadAssignArrayWithRand(array,num_arrays); start = clock(); for (i = 0; i < num_arrays; i++) { /* abase.ptrs.p+=i*ASSIGNROWS*ASSIGNCOLS; */ /* Fixed by Eike Dierks */ Assignment(*abase.ptrs.ap); abase.ptrs.p += ASSIGNROWS * ASSIGNCOLS; } stop = clock(); return stop - start; } /**************************** ** LoadAssignArrayWithRand ** ***************************** ** Load the assignment arrays with random numbers. All positive. ** These numbers represent costs. */ static void LoadAssignArrayWithRand(long *array, unsigned long num_arrays) { longptr abase,abase1; /* Local for array pointer */ unsigned long i; /* ** Set local array pointer */ abase.ptrs.p=array; abase1.ptrs.p=array; /* ** Set up the first array. Then just copy it into the ** others. */ LoadAssign(*(abase.ptrs.ap)); if(num_arrays>1) for(i=1;i