diff --git a/src/main_paralel.c b/src/main_paralel.c new file mode 100644 index 0000000000000000000000000000000000000000..41eed8d5c93f2295fdea439c9badab4144538700 --- /dev/null +++ b/src/main_paralel.c @@ -0,0 +1,134 @@ +#include <limits.h> +#include <stdlib.h> +#include <stdio.h> +#include <time.h> +#include <omp.h> + +#ifndef MAX +#define MAX 3000 +#endif + +int countMinimum(int n, int distance[],int visited[]); +void printToFile(int n, int startnode, int distance[]); +void dijkstra(int n, int **graph, int startnode); +void initGraph(int** graph, int n); + +void initGraph(int** graph, int n){ + for(int i=0; i<n; i++){ + int j=0; + while(j <= i){ + if(i==j){ + graph[i][j]=INT_MAX; + } + else{ + graph[i][j]= rand() % 1000000 + 1; + graph[j][i]=graph[i][j]; + } + j++; + } + } +} + +int countMinimum(int n, int distance[],int visited[]) { + int min = INT_MAX, min_index; + + for (int i = 0; i < n; i++) + if (visited[i] == 0 && distance[i] <= min) + min = distance[i], min_index = i; + + return min_index; +} + +void printToFile(int n, int startnode, int distance[]) { + FILE *fptr; + fptr = fopen("answer_paralel.txt","a"); + for(int i=0;i<n;i++) { + if(i!=startnode) + { + fprintf(fptr,"%d ",distance[i]); + } else { + fprintf(fptr,"%d ",0); + } + } + fprintf(fptr,"\n"); + fclose(fptr); +} + +// Function that implements Dijkstra's single source shortest path algorithm +// for a graph represented using adjacency matrix representation +void dijkstra(int n, int **graph, int startnode) { + int *distance, *visited; + distance=(int*)malloc(MAX*sizeof(int)); + visited=(int*)malloc(MAX*sizeof(int)); + + for(int i=0;i<n;i++) { + distance[i]=graph[startnode][i]; + visited[i]=0; + } + + distance[startnode]=0; + visited[startnode]=1; + + + // Find shortest path for all vertices + // #pragma omp parallel for num_threads(thread_count) + for (int count = 0; count < n - 1; count++) { + // int thread_count = omp_get_num_threads(); + // int my_rank = omp_get_thread_num(); + // printf("Hello from thread %d of %d\n", my_rank, thread_count); + // Pick the minimum distance vertex from the set of vertices not + // yet processed. u is always equal to startnode in the first iteration. + int u = countMinimum(n, distance, visited); + + // Mark the picked vertex as processed + visited[u] = 1; + + // Update distance value of the adjacent vertices of the picked vertex. + // #pragma omp parallel for num_threads(thread_count) + for (int i = 0; i < n; i++) + + // Update distance[i] only if is not in visited, there is an edge from + // u to i, and total weight of path from startnode to i through u is + // smaller than current value of distance[i] + if (!visited[i] && graph[u][i] && distance[u] != INT_MAX + && distance[u] + graph[u][i] < distance[i]) + distance[i] = distance[u] + graph[u][i]; + } + + // print the constructed distance array + printToFile(n, startnode, distance); + free(visited); + free(distance); +} + +// driver program to test above function +int main(int argc, char *argv[]) +{ + int **graph, n; + clock_t start, end; + int thread_count = strtol(argv[1], NULL, 10); + graph=(int**)malloc(MAX*sizeof(int*)); + for(int i=0;i<MAX;i++){ + graph[i]=(int*)malloc(MAX*sizeof(int)); + } + printf("Size of Matrix:"); + scanf("%d",&n); + srand(13517054); + + //Initialize graph node with random number + initGraph(graph, n); + + start = clock(); + #pragma omp parallel for num_threads(thread_count) + for (int startnode = 0; startnode < n ; startnode++) { + dijkstra(n, graph,startnode); + } + end = clock(); + printf("Waktu = %f microseconds\n", (double)(end - start)); + for (int i = 0; i < n; i++){ + free(graph[i]); + } + free(graph); + + return 0; +} diff --git a/src/main_serial.c b/src/main_serial.c index 27a9cefafae9fbf45a2cd07f3891d592b8973581..e7ecfe752f908a841303493c63c091c0173509bb 100644 --- a/src/main_serial.c +++ b/src/main_serial.c @@ -119,7 +119,11 @@ int main() } end = clock(); printf("Waktu = %f microseconds\n", (double)(end - start)); + for (int i = 0; i < n; i++){ + free(graph[i]); + } free(graph); + return 0; }