diff --git a/dijkstra.c b/dijkstra.c index c65c037c852a054e4a76c1043061c6633d898139..d3e99073183fef95157be767c0722a47d51053e2 100644 --- a/dijkstra.c +++ b/dijkstra.c @@ -4,113 +4,151 @@ #include <stdlib.h> #include <limits.h> -int NUMBER_OF_VERTICES = 0; +int N = 0; long getVertexWithMinDistance(long dist[], bool pickedVertices[]) { - long minDistance = LONG_MAX; - int vertexWithMinDistance = -1; - - for (int vertex = 0; vertex < NUMBER_OF_VERTICES; vertex++) { - if (!pickedVertices[vertex] && dist[vertex] <= minDistance) { - minDistance = dist[vertex]; - vertexWithMinDistance = vertex; + long minDistance = LONG_MAX; + int vertexWithMinDistance = -1; + + for (int vertex = 0; vertex < N; vertex++) { + if (!pickedVertices[vertex] && dist[vertex] <= minDistance) { + minDistance = dist[vertex]; + vertexWithMinDistance = vertex; + } } - } - return vertexWithMinDistance; + return vertexWithMinDistance; } -void dijkstra(int graph[NUMBER_OF_VERTICES][NUMBER_OF_VERTICES], int sourceVertex) { +long* dijkstra(int graph[N][N], int sourceVertex) { - // Distance from single source to all of the nodes - long dist[NUMBER_OF_VERTICES]; - bool pickedVertices[NUMBER_OF_VERTICES]; + // Distance from single source to all of the nodes + long *dist = (long*) malloc(sizeof(long) * N); + bool pickedVertices[N]; - for (int vertex = 0; vertex < NUMBER_OF_VERTICES; vertex++) { - if (vertex == sourceVertex) { - dist[vertex] = 0; - } else { - // Initialize all distance to be infinity. - dist[vertex] = LONG_MAX; + for (int vertex = 0; vertex < N; vertex++) { + if (vertex == sourceVertex) { + dist[vertex] = 0; + } else { + // Initialize all distance to be infinity. + dist[vertex] = LONG_MAX; + } + pickedVertices[vertex] = false; } - pickedVertices[vertex] = false; - } - for (int iteration = 0; iteration < NUMBER_OF_VERTICES - 1; iteration++) { - // Get minimum distance - int vertexWithMinDistance = getVertexWithMinDistance(dist, pickedVertices); + for (int iteration = 0; iteration < N - 1; iteration++) { + // Get minimum distance + int vertexWithMinDistance = getVertexWithMinDistance(dist, pickedVertices); + + // Mark the vertice as picked + pickedVertices[vertexWithMinDistance] = true; + + // Update distance value + for (int vertex = 0; vertex < N; vertex++) { + if ((!pickedVertices[vertex]) && + (graph[vertexWithMinDistance][vertex]) && + (dist[vertexWithMinDistance] != LONG_MAX) && + (dist[vertexWithMinDistance] + graph[vertexWithMinDistance][vertex] < dist[vertex])) { + // Change dist[] + dist[vertex] = dist[vertexWithMinDistance] + graph[vertexWithMinDistance][vertex]; + } + } + } - // Mark the vertice as picked - pickedVertices[vertexWithMinDistance] = true; + return dist; - // Update distance value - for (int vertex = 0; vertex < NUMBER_OF_VERTICES; vertex++) { - if (!pickedVertices[vertex] && graph[vertexWithMinDistance][vertex] && dist[vertexWithMinDistance] != LONG_MAX && dist[vertexWithMinDistance] + graph[vertexWithMinDistance][vertex] < dist[vertex]) { - dist[vertex] = dist[vertexWithMinDistance] + graph[vertexWithMinDistance][vertex]; - } - } - } - - // Edit the real graph - for (int vertex = 0; vertex < NUMBER_OF_VERTICES; vertex++) { - graph[sourceVertex][vertex] = dist[vertex]; - } - - // Print solution - for (int vertex = 0; vertex < NUMBER_OF_VERTICES; vertex++) { - // printf("%d to %ld\n", vertex, dist[vertex]); - printf("%d to %d\n", vertex, graph[sourceVertex][vertex]); - } + // // Print solution + // for (int vertex = 0; vertex < N; vertex++) { + // // printf("%d to %ld\n", vertex, dist[vertex]); + // printf("%d to %d\n", vertex, graph[sourceVertex][vertex]); + // } } int main(int argc, char *argv[]) { - // Get matrix size from argument vector in , convert to int - NUMBER_OF_VERTICES = strtol(argv[1], NULL, 10); - - // Initialize matrix - int graph[NUMBER_OF_VERTICES][NUMBER_OF_VERTICES]; - - // Seed with NIM: Edward Alexander Jaya - srand(13517115); - // Fill the matrix with rand() function - for (int i = 0; i < NUMBER_OF_VERTICES; i++) { - for (int j = 0; j < NUMBER_OF_VERTICES; j++) { - // Mod by 100 so the result won't be too big. - graph[i][j] = rand() % 100; + // Test function + + // for (int i = 0; i < N; i++) { + // for (int j = 0; j < N; j++) { + // scanf("%d", &graph[i][j]); + // } + // } + + // graph = { 0, 4, 0, 0, 0, 0, 0, 8, 0, + // 4, 0, 8, 0, 0, 0, 0, 11, 0, + // 0, 8, 0, 7, 0, 4, 0, 0, 2, + // 0, 0, 7, 0, 9, 14, 0, 0, 0, + // 0, 0, 0, 9, 0, 10, 0, 0, 0, + // 0, 0, 4, 14, 10, 0, 2, 0, 0, + // 0, 0, 0, 0, 0, 2, 0, 1, 6, + // 8, 11, 0, 0, 0, 0, 1, 0, 7, + // 0, 0, 2, 0, 0, 0, 6, 7, 0 }; + + // dijkstra(graph, 1); + + // // Print function + // printf("Matrix: \n"); + // for (int i = 0; i < N; i++) { + // for (int j = 0; j < N; j++) { + // printf("%d ", graph[i][j]); + // } + // printf("\n"); + // } + + // Get matrix size from argument vector in , convert to int + N = strtol(argv[1], NULL, 10); + + // Initialize matrix + int graph[N][N]; + + // Seed with NIM: Edward Alexander Jaya + srand(13517115); + // Fill the matrix with rand() function + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + // Mod by 100 so the result won't be too big. + graph[i][j] = rand() % 100; + } } - } - - // Test function - - // for (int i = 0; i < NUMBER_OF_VERTICES; i++) { - // for (int j = 0; j < NUMBER_OF_VERTICES; j++) { - // scanf("%d", &graph[i][j]); - // } - // } - - // graph = { 0, 4, 0, 0, 0, 0, 0, 8, 0, - // 4, 0, 8, 0, 0, 0, 0, 11, 0, - // 0, 8, 0, 7, 0, 4, 0, 0, 2, - // 0, 0, 7, 0, 9, 14, 0, 0, 0, - // 0, 0, 0, 9, 0, 10, 0, 0, 0, - // 0, 0, 4, 14, 10, 0, 2, 0, 0, - // 0, 0, 0, 0, 0, 2, 0, 1, 6, - // 8, 11, 0, 0, 0, 0, 1, 0, 7, - // 0, 0, 2, 0, 0, 0, 6, 7, 0 }; - - dijkstra(graph, 1); - - // Print function - printf("Matrix: \n"); - for (int i = 0; i < NUMBER_OF_VERTICES; i++) { - for (int j = 0; j < NUMBER_OF_VERTICES; j++) { - printf("%d ", graph[i][j]); + + MPI_Status Stat; + MPI_Init(&argc, &argv); + // rank is the id of processes, numtasks is the number of processes + int rank, numtasks; + MPI_Comm_size(MPI_COMM_WORLD, &numtasks); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + double start_time, end_time, total_time = 0.0; + + int numOfTaskPerProcess = N / (numtasks - 1); + int destinationRank = 0; + int tag = 1; + int vertex = 0; + + // for each thread, synchronize before start + MPI_Barrier(MPI_COMM_WORLD); + + // Do not count the initial synchronization time + start_time = MPI_Wtime(); + + if (rank == 0) { + long* dataRecv; + // Receive + MPI_Recv(&dataRecv, N, MPI_LONG, MPI_ANY_SOURCE, tag, MPI_COMM_WORLD, &Stat); + printf("Received from process %d ", MPI_ANY_SOURCE); + // To do: store in the array + free(dataRecv); + } else { + for (int vertex = (rank - 1) * numOfTaskPerProcess; vertex < (rank - 1) * numOfTaskPerProcess + numOfTaskPerProcess; vertex++) { + long* dataSend = dijkstra(graph, vertex); + MPI_Send(dataSend, N, MPI_LONG, destinationRank, tag, MPI_COMM_WORLD); + // Possible bug + free(dataSend); + } } - printf("\n"); - } - // Send argument vector - MPI_Init(&argc, &argv); - // dijkstra(graph, 0); - MPI_Finalize(); + // Synchronize again and count the time + MPI_Barrier(MPI_COMM_WORLD); + end_time = MPI_Wtime(); + total_time = end_time - start_time; + MPI_Finalize(); } diff --git a/prog b/prog index 36dc0edffef02f645890ce0603622a4818a177b6..bc7444f0404da1a31988e24d3001a7225c403486 100755 Binary files a/prog and b/prog differ