Skip to content
Snippets Groups Projects
Commit c2f2329e authored by harrymunli's avatar harrymunli
Browse files

basic function

parent 4ce86c7d
No related merge requests found
#include <stdio.h>
#include <stdlib.h>
#include </usr/include/mpi/mpi.h>
#include <time.h>
#include "func.h"
#define INFINITY 1000000
/*
Fungsi untuk membaca n (jumlah node yang akan digunakan)
*/
int Read_n(int rank, MPI_Comm com) {
int n;
if (rank == 0){
scanf("%d", &n);
}
MPI_Bcast(&n, 1, MPI_INT, 0, com);
return n;
}
/*
Membuat MPI_Datatype yang merepresentasikan matriks
*/
MPI_Datatype Build_blk_col_type(int n_local, int n) {
MPI_Datatype first_bc_mpi_t;
MPI_Datatype block_mpi_t;
MPI_Datatype blk_col_mpi_t;
MPI_Aint lb, extent;
MPI_Type_contiguous(n_local, MPI_INT, &block_mpi_t);
MPI_Type_get_extent(block_mpi_t, &lb, &extent);
MPI_Type_vector(n, n_local, n, MPI_INT, &first_bc_mpi_t);
MPI_Type_create_resized(first_bc_mpi_t, lb, extent, &blk_col_mpi_t);
MPI_Type_commit(&blk_col_mpi_t);
MPI_Type_free(&block_mpi_t);
MPI_Type_free(&first_bc_mpi_t);
return blk_col_mpi_t;
}
/*
Membuat sebuah matriks nxn yang mewakili graf.
Nilai M[i][j] = jarak dari node i ke j.
Jarak diinisialisasi dengan nilai random yang memiliki seed = 13517111.
*/
void Make_matrix(int tab_local[], int n_local, int n,
MPI_Datatype blk_col_mpi_t, int rank, MPI_Comm com) {
int upper = 1000;
int lower = 0;
int *mat = NULL, i, j;
srand(13517111);
if (rank == 0) {
mat = malloc(n * n * sizeof(int));
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
if(j==i) {
mat[i * n + j] = 0;
}
else if (j>i){
int x = (rand() % (upper - lower + 1)) + lower;
mat[i * n + j] = x;
mat[i + j * n] = x;
}
}
}
}
MPI_Scatter(mat, 1, blk_col_mpi_t, tab_local, n * n_local, MPI_INT, 0, com);
if (rank == 0) free(mat);
}
/*
Mencari jarak minimum lokal dari titik 0 ke sebuah simpul
*/
int Find_jarak_min(int jarak_local[], int known_local[], int n_local) {
int jarak_terpendek = INFINITY;
int v_local;
int u_local = -1;
for (v_local = 0; v_local < n_local; v_local++) {
if (!known_local[v_local]) {
if (jarak_local[v_local] < jarak_terpendek) {
jarak_terpendek = jarak_local[v_local];
u_local = v_local;
}
}
}
return u_local;
}
/*
Menuliskan setiap jarak dari titik 0 ke setiap simpul ke out.txt
*/
void Print_jarak(int jarak_global[], int n) {
int v;
FILE *fptr;
fptr = fopen("out.txt","w");
if(fptr == NULL){
printf("Error!");
exit(1);
}
fprintf(fptr," v dist 0->v\n");
fprintf(fptr,"---- ---------\n");
for (v = 1; v < n; v++) {
if (jarak_global[v] != INFINITY) {
fprintf(fptr,"%3d %4d\n", v, jarak_global[v]);
}
else
fprintf(fptr,"%3d %5s\n", v, "inf");
}
fprintf(fptr,"\n");
fclose(fptr);
}
/*
Menginisialisasi setiap matriks yang ada pada nodes agar algoritmanya bisa berjalan.
*/
void Dijkstra_Init(int tab_local[], int pred_local[], int jarak_local[], int known_local[],
int rank, int n_local) {
int loc_v;
if (rank == 0)
known_local[0] = 1;
else
known_local[0] = 0;
for (loc_v = 1; loc_v < n_local; loc_v++)
known_local[loc_v] = 0;
for (loc_v = 0; loc_v < n_local; loc_v++) {
jarak_local[loc_v] = tab_local[0 * n_local + loc_v];
pred_local[loc_v] = 0;
}
}
/*
Algoritma dijkstra untuk menghitung jarak terpendek dari simpul 0 ke setiap simpul lainnya.
*/
void Dijkstra(int tab_local[], int jarak_local[], int pred_local[], int n_local, int n,
MPI_Comm com) {
int i, jarak_baru, rank, v_local, u_local, global_u, jarak_global_u;
int *known_local;
int min_global[2];
int min[2];
MPI_Comm_rank(com, &rank);
known_local = malloc(n_local * sizeof(int));
Dijkstra_Init(tab_local, pred_local, jarak_local, known_local, rank, n_local);
/*
Membuat loop sebanyak n-1 kali karena jarak terpendek node 0 ke 0 adalah 0
*/
for (i = 0; i < n - 1; i++) {
u_local = Find_jarak_min(jarak_local, known_local, n_local);
if (u_local == -1) {
min[0] = INFINITY;
min[1] = -1;
}
else {
min[0] = jarak_local[u_local];
min[1] = u_local + rank * n_local;
}
/*
Menyimpan jarak terpendek global dan nodenya dalam min_global
*/
MPI_Allreduce(min, min_global, 1, MPI_2INT, MPI_MINLOC, com);
jarak_global_u = min_global[0];
global_u = min_global[1];
if (global_u == -1)
break;
if ((global_u / n_local) == rank) {
u_local = global_u % n_local;
known_local[u_local] = 1;
}
for (v_local = 0; v_local < n_local; v_local++) {
if (!known_local[v_local]) {
jarak_baru = jarak_global_u + tab_local[global_u * n_local + v_local];
if (jarak_baru < jarak_local[v_local]) {
pred_local[v_local] = global_u;
jarak_local[v_local] = jarak_baru;
}
}
}
}
free(known_local);
}
#include <stdio.h>
#include <stdlib.h>
#include </usr/include/mpi/mpi.h>
#include <time.h>
#ifndef FUNC_H
#define FUNC_H
int Read_n(int rank, MPI_Comm com);
MPI_Datatype Build_blk_col_type(int n_local, int n);
void Make_matrix(int tab_local[], int n_local, int n, MPI_Datatype blk_col_mpi_t,
int rank, MPI_Comm com);
int Find_jarak_min(int jarak_local[], int known_local[], int n_local);
void Print_jarak(int n, int jarak_global[]);
void Dijkstra_Init(int tab_local[], int pred_local[], int jarak_local[], int known_local[],
int rank, int n_local);
void Dijkstra(int tab_local[], int jarak_local[], int pred_local[], int n_local, int n,
MPI_Comm com);
#endif
\ No newline at end of file
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment