diff --git a/bucket_sort b/bucket_sort index c94acb33e0c63c86de8eed161d60619e74b0f0bb..7570f4683e5bd63db2a2ed625f0729c8744a52da 100755 Binary files a/bucket_sort and b/bucket_sort differ diff --git a/bucket_sort.c b/bucket_sort.c index 5de4d6cb72b575d926732f0bfa3208802cda3a47..83a990e761de4d61d859a7dfe0844a93c442de27 100644 --- a/bucket_sort.c +++ b/bucket_sort.c @@ -5,147 +5,153 @@ #include <assert.h> int *create_rand_nums(int num_elements) { - int *rand_nums = (int *)malloc(sizeof(int) * num_elements); - assert(rand_nums != NULL); - int i; - for (i = 0; i < num_elements; i++) { - rand_nums[i] = rand()%100 + 1; - printf("%d ", rand_nums[i]); - } - printf("\n"); - return rand_nums; + int *rand_nums = (int *)malloc(sizeof(int) * num_elements); + assert(rand_nums != NULL); + int i; + for (i = 0; i < num_elements; i++) { + rand_nums[i] = rand()%RAND_MAX + 1; + } + return rand_nums; } void searchMaxMin(int *array, int numElements, int *max, int *min) { - int i; - *min = array[0]; - *max = array[0]; - for (i=1; i<numElements; i++) { - if (*min > array[i]) { - *min = array[i]; - } - if (*max < array[i]) { - *max = array[i]; - } - } + int i; + *min = array[0]; + *max = array[0]; + for (i=1; i<numElements; i++) { + if (*min > array[i]) { + *min = array[i]; + } + if (*max < array[i]) { + *max = array[i]; + } + } } void divideBucket(int max, int min, int bucketNum, int *result) { - int gap = (max-min)/bucketNum; - int remain = (max-min)%bucketNum; - int i; - result = (int *)malloc(sizeof(int) * (bucketNum+1)); - result[0] = min; - printf("%d\n", result[0]); - for (i=1; i<bucketNum; i++) { - result[i] = result[i-1] + gap; - printf("%d ", result[i]); - } - result[i+1] = max; - printf("%d\n", result[i+1]); + int gap = (max-min)/bucketNum; + int remain = (max-min)%bucketNum; + int i; + + result[0] = min; + for (i=1; i<bucketNum; i++) { + result[i] = result[i-1] + gap; + } + result[i] = max; } void sort(int *array, int num_elements) { - int sum = 0; - int i, j, k; - for (i = 1; i <= num_elements-1; i++) { - j = i; - - while(j>0 && array[j] < array[j-1]) { - k = array[j]; - array[j] = array[j-1]; - array[j-1] = k; - j--; - } - } + int sum = 0; + int i, j, k; + for (i = 1; i <= num_elements-1; i++) { + j = i; + + while(j>0 && array[j] < array[j-1]) { + k = array[j]; + array[j] = array[j-1]; + array[j-1] = k; + j--; + } + } } int main(int argc, char** argv) { - int bucketNum, rank, dest, source, rc, count, tag=1; - MPI_Status Stat; - - MPI_Init(&argc,&argv); - MPI_Comm_size(MPI_COMM_WORLD, &bucketNum); - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - - int numElements = atoi(argv[1]); - - if (rank == 0) { - // Random array - int *num = NULL; - num = create_rand_nums(numElements); - - int min, max; - searchMaxMin(num, numElements, &max, &min); - printf("%d %d\n", max, min); - - int *bucketRange = NULL; - divideBucket(max, min, bucketNum, bucketRange); - - // Bagi angka random ke bucket - int buckets[bucketNum][numElements]; - int bucketsSize[bucketNum]; - int i; - for (i=0; i<bucketNum; i++) { - bucketsSize[i] = 0; - } - - int j, isFound; - for (i=0; i<numElements; i++) { - j = 0; - isFound = 0; - while (j<bucketNum && !isFound) { - if ((num[i] >= bucketRange[j]) && (num[i] < bucketRange[j+1]-1)) { - bucketsSize[j]++; - buckets[j][bucketsSize[j]] = num[i]; - isFound = 1; - } else { - j++; - } - } - } - for (i=0; i<bucketNum; i++) { - for (j=0; j<bucketsSize[i]; j++) { - printf("%d ", buckets[j]); - } - printf("\n"); - } - - // Kirim - for (i=1; i<bucketNum; i++) { - rc = MPI_Send(&bucketsSize[i], 1, MPI_INT, i, tag, MPI_COMM_WORLD); - rc = MPI_Send(&buckets[i], bucketsSize[i], MPI_INT, i, tag, MPI_COMM_WORLD); - } - - // Sort diri sendiri - sort(buckets[0], bucketsSize[0]); - for (i=0; i<bucketsSize[0]; i++) { - printf("%d ", buckets[0][i]); - } - - for (i=1; i<bucketNum; i++) { - int size = bucketsSize[i]; - int temp[size]; - rc = MPI_Recv(&temp, bucketsSize[i], MPI_INT, i, tag, MPI_COMM_WORLD, &Stat); - - for (i=0; i<size; i++) { - printf("%d ", temp[i]); - } - } - } else { - int bucketSize; - rc = MPI_Recv(&bucketSize, 1, MPI_INT, source, tag, MPI_COMM_WORLD, &Stat); - - int *numIn; - source = 0; - rc = MPI_Recv(&numIn, bucketSize, MPI_INT, source, tag, MPI_COMM_WORLD, &Stat); - - // Sorting - sort(numIn, bucketSize); - dest = 0; - rc = MPI_Send(&numIn, bucketSize, MPI_INT, dest, tag, MPI_COMM_WORLD); - } - - MPI_Finalize(); + int bucketNum, rank, dest, source, rc, count, tag=1; + clock_t beginTime, endTime; + MPI_Status Stat; + + beginTime = clock(); + MPI_Init(&argc,&argv); + MPI_Comm_size(MPI_COMM_WORLD, &bucketNum); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + int numElements = atoi(argv[1]); + + + if (rank == 0) { + // Random array + int *num = NULL; + num = create_rand_nums(numElements); + + int min, max; + searchMaxMin(num, numElements, &max, &min); + + int *bucketRange = NULL; + bucketRange = (int *)malloc(sizeof(int) * (bucketNum+1)); + divideBucket(max, min, bucketNum, bucketRange); + + // Bagi angka random ke bucket + int buckets[bucketNum][numElements]; + int bucketsSize[bucketNum]; + int i; + for (i=0; i<bucketNum; i++) { + bucketsSize[i] = 0; + } + + int j, isFound; + for (i=0; i<numElements; i++) { + j = 0; + isFound = 0; + while (j<bucketNum && !isFound) { + if (j == 0) { + if ((num[i] >= bucketRange[j]) && (num[i] <= bucketRange[j+1])) { + buckets[j][bucketsSize[j]] = num[i]; + bucketsSize[j]++; + isFound = 1; + } else { + j++; + } + } else { + if ((num[i] >= bucketRange[j]+1) && (num[i] <= bucketRange[j+1])) { + buckets[j][bucketsSize[j]] = num[i]; + bucketsSize[j]++; + isFound = 1; + } else { + j++; + } + } + } + } + + // Kirim + for (i=1; i<bucketNum; i++) { + rc = MPI_Send(&bucketsSize[i], 1, MPI_INT, i, 1, MPI_COMM_WORLD); + rc = MPI_Send(buckets[i], bucketsSize[i], MPI_INT, i, 2, MPI_COMM_WORLD); + } + + //Sort diri sendiri + sort(buckets[0], bucketsSize[0]); + // for (i=0; i<bucketsSize[0]; i++) { + // printf("%d\n", buckets[0][i]); + // } + + for (i=1; i<bucketNum; i++) { + int size = bucketsSize[i]; + int temp[size]; + rc = MPI_Recv(temp, bucketsSize[i], MPI_INT, i, 3, MPI_COMM_WORLD, &Stat); + // for (i=0; i<size; i++) { + // printf("%d\n", temp[i]); + // } + } + endTime = clock(); + printf("Execution time: %f seconds\n", (double)(endTime-beginTime)/CLOCKS_PER_SEC); + } else { + int bucketSize; + source = 0; + rc = MPI_Recv(&bucketSize, 1, MPI_INT, source, 1, MPI_COMM_WORLD, &Stat); + int *numIn = (int *)malloc(sizeof(int) * (bucketSize));; + source = 0; + rc = MPI_Recv(numIn, bucketSize, MPI_INT, source, 2, MPI_COMM_WORLD, &Stat); + + // Sorting + sort(numIn, bucketSize); + dest = 0; + rc = MPI_Send(numIn, bucketSize, MPI_INT, dest, 3, MPI_COMM_WORLD); + } + + MPI_Barrier(MPI_COMM_WORLD); + MPI_Finalize(); + } + diff --git a/laporan.txt b/laporan.txt index 82839fa38a4a64e78ee0ae8a6708cf2b7462e158..53b45be1750fa71fad09ecab2578577583f5ac58 100644 --- a/laporan.txt +++ b/laporan.txt @@ -1 +1,24 @@ -- Test Case 1 (N = 50000) M = 1 -> M = 4 -> M = 8 -> M = 16 -> M = 32 -> - Test Case 2 (N = 100000) M = 1 -> M = 4 -> M = 8 -> M = 16 -> M = 32 -> - Test Case 3 (N = 200000) M = 1 -> M = 4 -> M = 8 -> M = 16 -> M = 32 -> - Test Case 4 (N = 400000) M = 1 -> M = 4 -> M = 8 -> M = 16 -> M = 32 -> +- Test Case 1 (N = 50000) + M = 1 -> 3.38 s + M = 4 -> 0.27 s + M = 8 -> 0.22 s + M = 16 -> 0.13 s + M = 32 -> 0.1 s + +- Test Case 2 (N = 100000) + M = 1 -> 13.14 s + M = 4 -> 1.11 s + M = 8 -> 0.58 s + M = 16 -> 0.32 s + M = 20 -> 0.15 s + +- Test Case 3 (N = 200000) + M = 1 -> 52.52 s + M = 4 -> 3.62 s + M = 8 -> 2.22 s + M = 10 -> 1.47 s + +- Test Case 4 (N = 400000) + M = 1 -> 211.21 s + M = 4 -> 17.25 s + M = 5 -> 8.97 s