diff --git a/README.md b/README.md index da1c267a1e4d9bda24d493a331eb6a26eb185719..bea9b0fbacdcc679c66c3853d45e2c1c22e749af 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,8 @@ # if3230_mp_mst +Cara compile program OpenMP: +gcc -o MST_OpenMP.out MST_OpenMP.c + +Cara menjalankan program OpenMP: +./MST_OpenMP.out < "../test/test_case_01" +./MST_OpenMP.out \ No newline at end of file diff --git a/src/MST_OpenMP b/src/MST_OpenMP index bd3592b945561c7078d02e3a191cd7487125fa65..31321e2fd1b102ccd7c68b1d6467c0d5478aa3f0 100755 Binary files a/src/MST_OpenMP and b/src/MST_OpenMP differ diff --git a/src/MST_OpenMP.c b/src/MST_OpenMP.c index 24455ca754950efc1dffad7d444abca020f799e5..2abc5eaa62e4dc88e2632afcdc4c4154120cf9f2 100644 --- a/src/MST_OpenMP.c +++ b/src/MST_OpenMP.c @@ -87,6 +87,8 @@ void bubbleSort(Edge arr[], int n, int type) } } } + +/// Create graph based from the adjacency matrix in file Graph *ReadArguments() { Graph *graph = (Graph *)(malloc(sizeof(Graph))); @@ -118,58 +120,6 @@ Graph *ReadArguments() return graph; } - -// Create graph based from the adjacency matrix in file -Graph *ReadFile(char fileName[]) -{ - FILE *fptr; - char fileURL[] = "../test/"; - strcat(fileURL, fileName); - fptr = fopen(fileURL, "r"); - - if (fptr == NULL) - { - printf("Error! Opening file"); - exit(1); - } - - Graph *graph = (Graph *)(malloc(sizeof(Graph))); - - int V; - scanf(fptr, "%d ", &V); - graph->V = V; - graph->edge = (Edge *)(malloc(((V * V - V) / 2) * sizeof(Edge))); - - // Read the adjacency matrix - int E = 0; - - /* -I/O cannot be parallized -src : http://forum.openmp.org/forum/viewtopic.php?f=3&t=764 -In general reading and writing from a file from multiple threads is not a good idea unless the underlying operating system or I/O system really supports it (commonly referred to as parallel I/O). -A lot of times the I/O routines can be used to read/write from separate files at the same time. That is because each I/O instance is keeping it's own data area telling which line it is reading or writing from. However, when you have multiple threads trying to read/write to the same file you need the I/O system to keep one data area for that file for all threads. This is not what is generally done, so you end up serializing (or somehow locking) the I/O. This of course, slows done the process and thus makes parallelizing I/O relatively impractical (since you will not see a speedup) - */ - for (int i = 0; i < V; i++) - { - for (int j = 0; j < V; j++) - { - int weight; - scanf(fptr, "%d", &weight); - // printf("%d ", weight); - if ((weight != -1) && (i <= j)) - { - graph->edge[E].src = i; - graph->edge[E].dest = j; - graph->edge[E].weight = weight; - E += 1; - } - } - } - // printf("\n"); - graph->E = E; - return graph; -} - // Structure to represent a subset for union-find typedef struct { @@ -238,7 +188,7 @@ int compare_src(const void *a, const void *b) } // Minimum Spanning Tree using Kruskal's Algorithm -void KruskalMST(Graph *graph, Edge *result, int *e) +void KruskalMST(Graph *graph, Edge result[], int *e) { int V = graph->V; int i = 0; @@ -257,7 +207,6 @@ void KruskalMST(Graph *graph, Edge *result, int *e) int x = find(subsets, next_edge.src); int y = find(subsets, next_edge.dest); - if (x != y) { result[(*e)++] = next_edge; @@ -286,17 +235,18 @@ void printResult(Edge *result, int e) printf("%d-%d\n", result[i].src, result[i].dest); } } + // Driver program to test above functions int main() { Graph *graph = ReadArguments(); - Edge result; - int e; + Edge result[graph->V]; + int e = 0; // PrintGraph(graph); int t = clock(); - KruskalMST(graph, &result, &e); + KruskalMST(graph, result, &e); t = clock() - t; - printResult(&result, e); - printf("Waktu Eksekusi: %f ms", ((double)t) / CLOCKS_PER_SEC * 1000); + printResult(result, e); + printf("Waktu Eksekusi: %f ms\n", ((double)t) / CLOCKS_PER_SEC * 1000); return 0; } \ No newline at end of file diff --git a/src/MST_OpenMP.exe b/src/MST_OpenMP.exe deleted file mode 100644 index 1f2aa1944a97aa5adb8acbf908532b7ce3a50f2b..0000000000000000000000000000000000000000 Binary files a/src/MST_OpenMP.exe and /dev/null differ diff --git a/src/MST_Serial b/src/MST_Serial index bea1adf661965ac3d204c4f6295699fcced39a09..3927436b13eb5c70e4182cc7a394f42e3bebbc5a 100755 Binary files a/src/MST_Serial and b/src/MST_Serial differ diff --git a/src/MST_Serial.c b/src/MST_Serial.c index 19967b51be573df4263aad055ba3277929df9f60..3da1b6347e3b4141f85a1a5ac174c11afe3457f3 100644 --- a/src/MST_Serial.c +++ b/src/MST_Serial.c @@ -43,7 +43,39 @@ void PrintGraph(Graph *graph) printf("%d -- %d = %d\n", graph->edge[i].src, graph->edge[i].dest, graph->edge[i].weight); } } +void bubbleSort(Edge arr[], int n, int type) +{ + //Jika type ==1, maka diurutkan berdasarkan weight + //Jika type ==2, maka diurutkan berdasarkan src + int i, j; + for (i = 0; i < n - 1; i++) + for (j = 0; j < n - i - 1; j++) + if (type == 1) + { + if (arr[j].weight > arr[j + 1].weight) + { + Edge temp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = temp; + } + } + else + { + if (arr[j].src > arr[j + 1].src) + { + Edge temp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = temp; + } + else if (arr[j].src == arr[j + 1].src && arr[j].dest > arr[j + 1].dest) + { + Edge temp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = temp; + } + } +} // Create graph based from the adjacency matrix in file Graph *ReadArguments() { @@ -143,55 +175,64 @@ int compare_src(const void *a, const void *b) } // Minimum Spanning Tree using Kruskal's Algorithm -void KruskalMST(Graph *graph) +void KruskalMST(Graph *graph, Edge result[], int *e) { int V = graph->V; - Edge result[V]; - int e = 0; int i = 0; // Step 1: Sort all the edges into correspondent sorted edges - qsort(graph->edge, graph->E, sizeof(graph->edge[0]), compare); + // qsort(graph->edge, graph->E, sizeof(graph->edge[0]), compare); + bubbleSort(graph->edge, graph->E, 1); // Step 2: Allocate memory for creating V subsets Subset *subsets = CreateSubset(V); - while ((e < V - 1) && (i < graph->E)) + + while (((*e) < V - 1) && (i < graph->E)) { // Pick the smallest edge of the graph Edge next_edge = graph->edge[i++]; int x = find(subsets, next_edge.src); int y = find(subsets, next_edge.dest); - if (x != y) { - result[e++] = next_edge; + result[(*e)++] = next_edge; Union(subsets, x, y); } } - // Print all minimum spanning tree edges + bubbleSort(result, (*e), 2); + return; + // qsort(result, e, sizeof(result[0]), compare_src); +} - qsort(result, e, sizeof(result[0]), compare_src); - printf("Minimum Spanning Tree Edges\n"); +void printResult(Edge *result, int e) +{ + // printf("%d\n", e); int minimumCost = 0; - for (i = 0; i < e; i++) + for (int i = 0; i < e; i++) { - printf("%d -- %d == %d\n", result[i].src, result[i].dest, result[i].weight); minimumCost += result[i].weight; } - printf("Minimum cost spanning tree: %d", minimumCost); - return; + printf("%d\n", minimumCost); + for (int i = 0; i < e; i++) + { + printf("%d-%d\n", result[i].src, result[i].dest); + } } + // Driver program to test above functions int main() { Graph *graph = ReadArguments(); - PrintGraph(graph); + Edge result[graph->V]; + int e = 0; + // PrintGraph(graph); int t = clock(); - KruskalMST(graph); + KruskalMST(graph, result, &e); t = clock() - t; - printf("\n\nWaktu Eksekusi: %f ms", ((double)t) / CLOCKS_PER_SEC * 1000); + printResult(result, e); + printf("Waktu Eksekusi: %f ms\n", ((double)t) / CLOCKS_PER_SEC * 1000); return 0; } \ No newline at end of file diff --git a/src/MST_Serial.exe b/src/MST_Serial.exe deleted file mode 100644 index a27ad175acd9eb19d5a6dcf6e743717a58862686..0000000000000000000000000000000000000000 Binary files a/src/MST_Serial.exe and /dev/null differ