/* Implements the two- and three-dimensional rank-finding algorithms * * described in the paper: Jon Louis Bentley, "Multidimensional * * Divide-and-Conquer", Cummunications of ACM, 23(4), April 1980, 214--229. * * * * Running times: O(n log n) in 2-d, and O(n log^2 n) in 3-d. * * * * Implemented by: Abhijit Das, Date: 08-October-2014 */ #include #include #include /* Default number of points */ #define N 64 typedef struct { double coord[3]; /* The three coordinates x, y and z */ int ypart, zpart; /* One of the two halves to which a point belongs during merging */ } point; /* Randomly generate n points in the unit square */ point *genpoints ( int n ) { point *A; int i; A = (point *)malloc(n * sizeof(point)); for (i=0; i i2) index[k] = idx[j++]; else if (j > j2) index[k] = idx[i++]; else if (A[idx[i]].coord[c] < A[idx[j]].coord[c]) index[k] = idx[i++]; else index[k] = idx[j++]; ++k; } for (k=0; k A[j].coord[0]) && (A[i].coord[1] > A[j].coord[1])) sid[i]++; else if ((A[i].coord[0] < A[j].coord[0]) && (A[i].coord[1] < A[j].coord[1])) sid[j]++; } } } /* Functions for computing ranks (superiority indices) in 3-d space. Input variables: The array A with n points, and the sorted index arrays for each of the three dimensions (zidx, yidx and xidx). Output variables: Increment the ranks in sid[] */ void calcsupidx3 ( point *A, int n, int *zidx, int *yidx, int *xidx, int *sid ) { int i, j, k0, k1; int *xidx0, *xidx1, *yidx0, *yidx1; int *zpart; if (n <= 1) return; /* In 3-d, we first divide A with respect to the z-coordinate values. L consists of half of the points with the lower z-coordinates, and H consists of half of the points with the higher z-coordinates. The merging step requires remembering whether a point in A is from L or from H. So we modify the zpart values of these points. But before doing that, we remember the old zpart values of the points in the local array zpart[]. */ zpart = (int *)malloc(n * sizeof(int)); for (i=0; i<(n+1)/2; ++i) { j = zidx[i]; zpart[i] = A[j].zpart; A[j].zpart = 0; } for (i=0; i A[j].coord[0]) && (A[i].coord[1] > A[j].coord[1]) && (A[i].coord[2] > A[j].coord[2])) sid[i]++; else if ((A[i].coord[0] < A[j].coord[0]) && (A[i].coord[1] < A[j].coord[1]) && (A[i].coord[2] < A[j].coord[2])) sid[j]++; } } } int main ( int argc, char *argv[] ) { int n, i; int *xidx, *yidx, *zidx; int *supidx; point *A; srand((unsigned int)time(NULL)); if (argc > 1) n = atoi(argv[1]); else n = N; A = genpoints(n); xidx = (int *)malloc(n * sizeof(int)); yidx = (int *)malloc(n * sizeof(int)); zidx = (int *)malloc(n * sizeof(int)); for (i=0; i