diff --git a/src/MST_OpenMP b/src/MST_OpenMP deleted file mode 100755 index 31321e2fd1b102ccd7c68b1d6467c0d5478aa3f0..0000000000000000000000000000000000000000 Binary files a/src/MST_OpenMP and /dev/null differ diff --git a/src/MST_OpenMP.c b/src/MST_OpenMP.c index 6b8963f3136a2575f872cec58e7e58b7894ba95d..757d567f3cffdcd4e6796db0587833ede7bd2267 100644 --- a/src/MST_OpenMP.c +++ b/src/MST_OpenMP.c @@ -245,7 +245,7 @@ int main() int t = clock(); KruskalMST(graph, result, &e); t = clock() - t; - printf("Waktu Eksekusi: %f ms \n", ((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.out b/src/MST_OpenMP.out deleted file mode 100755 index 81f11debdaf328022fa25db0eb3d50a202cea1f0..0000000000000000000000000000000000000000 Binary files a/src/MST_OpenMP.out and /dev/null differ diff --git a/src/MST_OpenMPI.c b/src/MST_OpenMPI.c new file mode 100644 index 0000000000000000000000000000000000000000..ed877dbf584f19035e5b9c881c214da4960e1660 --- /dev/null +++ b/src/MST_OpenMPI.c @@ -0,0 +1,259 @@ +// IF3230 - Sistem Paralel dan Terdistribusi +// Michael Hans / 13518056 +// Kevin Austin Stefano / 13518104 + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <mpi.h> + +// Edge structure +typedef struct +{ + int src; + int dest; + int weight; +} Edge; + +// Graph structure +typedef struct +{ + int V; // number of vertices + int E; // number of edges + Edge *edge; +} Graph; + +// Create new Graph based on V vertices and E edges +Graph *CreateGraph(int V, int E) +{ + Graph *graph = (Graph *)(malloc(sizeof(Graph))); + graph->V = V; + graph->E = E; + graph->edge = (Edge *)(malloc(E * sizeof(Edge))); + return graph; +} + +// Print all graph component to the CLI +void PrintGraph(Graph *graph) +{ + printf("Vertices : %d\n", graph->V); + printf("Edges : %d\n", graph->E); + for (int i = 0; i < graph->E; i++) + { + printf("%d -- %d = %d\n", graph->edge[i].src, graph->edge[i].dest, graph->edge[i].weight); + } +} + +// A function to implement bubble sort +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; +// #pragma omp parallel num_threads(thread_count) default(none) private(i, j) shared(type, arr, n) + 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) + { +// #pragma omp critical + { + Edge temp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = temp; + } + } + } + else + { + if (arr[j].src > arr[j + 1].src) +// #pragma omp critical + { + 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) +// #pragma omp critical + { + Edge temp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = temp; + } + } +} + +/// Create graph based from the adjacency matrix in file +Graph *ReadArguments() +{ + Graph *graph = (Graph *)(malloc(sizeof(Graph))); + + int V, weight; + scanf("%d", &V); + graph->V = V; + graph->edge = (Edge *)(malloc(((V * V - V) / 2) * sizeof(Edge))); + + // Read the adjacency matrix + int E = 0; + for (int i = 0; i < V; i++) + { + for (int j = 0; j < V; j++) + { + scanf("%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 +{ + int parent; + int rank; +} Subset; + +// Create new subset +Subset *CreateSubset(int V) +{ + Subset *subsets = (Subset *)(malloc(V * sizeof(Subset))); + +// Create V subsets with single elements +// #pragma omp parallel for num_threads(thread_count) + for (int i = 0; i < V; i++) + { + subsets[i].parent = i; + subsets[i].rank = 0; + } + return subsets; +} + +int find(Subset subsets[], int i) +{ + // find root and make root as parent of i + // (path compression) + if (subsets[i].parent != i) + subsets[i].parent = find(subsets, subsets[i].parent); + return subsets[i].parent; +} + +void Union(Subset subsets[], int x, int y) +{ + int xroot = find(subsets, x); + int yroot = find(subsets, y); + + // Attach smaller rank tree under root of high + // rank tree (Union by Rank) + if (subsets[xroot].rank < subsets[yroot].rank) + subsets[xroot].parent = yroot; + else if (subsets[xroot].rank > subsets[yroot].rank) + subsets[yroot].parent = xroot; + + // If ranks are same, then make one as root and + // increment its rank by one + else + { + subsets[yroot].parent = xroot; + subsets[xroot].rank++; + } +} + +// Compare two edges according to their weights. +int compare(const void *a, const void *b) +{ + Edge *a1 = (Edge *)a; + Edge *b1 = (Edge *)b; + return a1->weight > b1->weight; +} + +int compare_src(const void *a, const void *b) +{ + Edge *a1 = (Edge *)a; + Edge *b1 = (Edge *)b; + return a1->src > b1->src; +} + +// Minimum Spanning Tree using Kruskal's Algorithm +void KruskalMST(Graph *graph, Edge result[], int *e) +{ + int V = graph->V; + int i = 0; + + // Step 1: Sort all the edges into correspondent sorted edges + // 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)) + { + // 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; + Union(subsets, x, y); + } + } + + bubbleSort(result, (*e), 2); + return; + // qsort(result, e, sizeof(result[0]), compare_src); +} + +void printResult(Edge *result, int e) +{ + // printf("%d\n", e); + int minimumCost = 0; +// #pragma omp parallel for + for (int i = 0; i < e; i++) + { +// #pragma omp critical + minimumCost += result[i].weight; + } + 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(int argc, char** argv) +{ + MPI_Init(NULL, NULL); + // Get the number of processes + int world_size; + MPI_Comm_size(MPI_COMM_WORLD, &world_size); + + // Get the rank of the process + int world_rank; + MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); + + + Graph *graph = ReadArguments(); + Edge result[graph->V]; + int e = 0; + int t = clock(); + KruskalMST(graph, result, &e); + t = clock() - t; + printResult(result, e); + printf("Waktu Eksekusi: %f ms \n", ((double)t) / CLOCKS_PER_SEC * 1000); + MPI_Finalize(); +} \ No newline at end of file diff --git a/src/MST_Serial b/src/MST_Serial deleted file mode 100755 index 3927436b13eb5c70e4182cc7a394f42e3bebbc5a..0000000000000000000000000000000000000000 Binary files a/src/MST_Serial and /dev/null differ diff --git a/src/hello b/src/hello new file mode 100755 index 0000000000000000000000000000000000000000..1de23036653bc3c34fc555ce1c6d1e0e66f45edb Binary files /dev/null and b/src/hello differ