bokunda

Celija

Apr 16th, 2021 (edited)
830
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.83 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <mpi.h>
  4.  
  5. #define KANCER 0
  6. #define LEK 1
  7. #define TKIVO 2
  8.  
  9. #define KANCER_VEROVATNOCA 2
  10. #define LEK_VEROVATNOCA 18
  11. #define TKIVO_VEROVATNOCA 80
  12.  
  13. #define TOP 1
  14. #define BOTTOM 2
  15. #define LEFT 4
  16. #define RIGHT 8
  17.  
  18. typedef struct celija {
  19.     int tip;
  20.     int jacina;
  21. } CELIJA;
  22.  
  23.  
  24. CELIJA** allocateMatrix(int m, int n)
  25. {
  26.     int i;
  27.     CELIJA **matrix = (CELIJA**)malloc(m * sizeof(CELIJA*));
  28.     for(i = 0; i < m; i++) matrix[i] = (CELIJA*)malloc(n * sizeof(CELIJA));
  29.     return matrix;
  30. }
  31.  
  32. void printMatrix(CELIJA **matrix, int startM, int m, int n)
  33. {
  34.     int i, j;
  35.     for (i = 0; i < m && startM <= m; i++)
  36.     {
  37.         for (j = 0; j < n; j++)
  38.         {
  39.             printf("| %d %6d ", matrix[i][j].tip, matrix[i][j].jacina);
  40.             if (j == n - 1) printf("|");
  41.         }
  42.         printf("\n");
  43.     }
  44. }
  45.  
  46. void setMatrixData(CELIJA **matrix, int m, int n)
  47. {
  48.     int i, j;
  49.     for (i = 0; i < m; i++)
  50.     {
  51.         for (j = 0; j < n; j++)
  52.         {
  53.             int verovatnocaTipa = rand() % 100 + 1;
  54.             if (verovatnocaTipa <= KANCER_VEROVATNOCA)
  55.             {
  56.                 matrix[i][j].tip = KANCER;
  57.                 matrix[i][j].jacina = rand() % 101 + 1;
  58.             }
  59.             else if (verovatnocaTipa > KANCER_VEROVATNOCA && verovatnocaTipa <= LEK_VEROVATNOCA)
  60.             {
  61.                 matrix[i][j].tip = LEK;
  62.                 matrix[i][j].jacina = rand() % 20 + 1;
  63.             }
  64.             else if (verovatnocaTipa > LEK_VEROVATNOCA)
  65.             {
  66.                 matrix[i][j].tip = TKIVO;
  67.                 matrix[i][j].jacina = rand() % 10001;
  68.             }
  69.         }
  70.     }
  71. }
  72.  
  73. int tryApplyCancerOrMedicine(CELIJA **matrix, int i, int j, CELIJA value)
  74. {
  75.     if (matrix[i][j].tip == TKIVO && value.tip == KANCER)
  76.     {
  77.         matrix[i][j].jacina -= value.jacina;
  78.  
  79.         if (matrix[i][j].jacina <= 0)
  80.         {
  81.             matrix[i][j].tip = KANCER;
  82.             matrix[i][j].jacina = rand() % 101;
  83.         }
  84.     }
  85.  
  86.     if (matrix[i][j].tip == KANCER && value.tip == LEK)
  87.     {
  88.         matrix[i][j].jacina -= value.jacina;
  89.        
  90.         if (matrix[i][j].jacina <= 0)
  91.         {
  92.             matrix[i][j].tip = TKIVO;
  93.             matrix[i][j].jacina = rand() % 10001;
  94.         }
  95.     }
  96.  
  97.     return matrix[i][j].tip != value.tip ? 1 : 0;
  98. }
  99.  
  100. void doWork(CELIJA **matrix, int startM, int endM, int n)
  101. {
  102.     int i, j;
  103.     for (i = startM; i <= endM; i++)
  104.     {
  105.         int hasCancerNeighbour = 0;
  106.         for (j = 0; j < n; j++)
  107.         {
  108.             // check left
  109.             if (j > 0) hasCancerNeighbour += tryApplyCancerOrMedicine(matrix, i, j, matrix[i][j-1]);
  110.             // check right
  111.             if (j < n) hasCancerNeighbour += tryApplyCancerOrMedicine(matrix, i, j, matrix[i][j+1]);
  112.             // check top
  113.             if (i > startM) hasCancerNeighbour += tryApplyCancerOrMedicine(matrix, i, j, matrix[i-1][j]);
  114.             // check bottom
  115.             if (i < endM) hasCancerNeighbour += tryApplyCancerOrMedicine(matrix, i, j, matrix[i+1][j]);
  116.             // check top-left
  117.             if (j > 0 && i > startM) hasCancerNeighbour += tryApplyCancerOrMedicine(matrix, i, j, matrix[i-1][j-1]);
  118.             // check top-right
  119.             if (j < n && i > startM) hasCancerNeighbour += tryApplyCancerOrMedicine(matrix, i, j, matrix[i-1][j+1]);
  120.             // check bottom-left
  121.             if (j > 0 && i < endM) hasCancerNeighbour += tryApplyCancerOrMedicine(matrix, i, j, matrix[i+1][j-1]);
  122.             // check bottom-right
  123.             if (j < n && i < endM) hasCancerNeighbour += tryApplyCancerOrMedicine(matrix, i, j, matrix[i+1][j+1]);
  124.  
  125.             // convert cell into a tissue if there cell is surrounded with tissues
  126.             if (hasCancerNeighbour == 0 && matrix[i][j].tip == LEK)
  127.             {
  128.                 matrix[i][j].tip = TKIVO;
  129.                 matrix[i][j].jacina = rand() % 10001;
  130.             }
  131.         }
  132.     }
  133. }
  134.  
  135. void doWorkEdge(CELIJA **matrix, CELIJA *rowToCompare, int n, int i)
  136. {
  137.     int j;
  138.     int hasCancerNeighbour = 0;
  139.     for (j = 0; j < n; j++)
  140.     {
  141.         // default check
  142.         hasCancerNeighbour += tryApplyCancerOrMedicine(matrix, i, j, rowToCompare[j]);
  143.  
  144.         // check edge-left
  145.         if (j > 0) hasCancerNeighbour += tryApplyCancerOrMedicine(matrix, i, j, rowToCompare[j-1]);
  146.         // check edge-right
  147.         if (j < n) hasCancerNeighbour += tryApplyCancerOrMedicine(matrix, i, j, rowToCompare[j+1]);
  148.  
  149.         if (hasCancerNeighbour == 0 && matrix[i][j].tip == LEK)
  150.         {
  151.             matrix[i][j].tip = TKIVO;
  152.             matrix[i][j].jacina = rand() % 10001;
  153.         }
  154.     }
  155. }
  156.  
  157. CELIJA findLocalStrongestCancerCell(CELIJA **matrix, int startM, int endM, int n)
  158. {
  159.     int i, j;
  160.     CELIJA strongest;
  161.     strongest.tip = KANCER;
  162.     strongest.jacina = -1;
  163.  
  164.     for (i = startM; i <= endM; i++)
  165.     {
  166.         for (j = 0; j < n; j++)
  167.         {
  168.             if (matrix[i][j].tip == KANCER && matrix[i][j].jacina > strongest.jacina)
  169.             {
  170.                 strongest = matrix[i][j];
  171.             }
  172.         }
  173.     }
  174.     return strongest;
  175. }
  176.  
  177. int main(int argc, char **argv)
  178. {
  179.     int rank, size;
  180.     int m = 100, n = 10;
  181.     int i;
  182.     int steps = 1;
  183.  
  184.     CELIJA strongestGlobal;
  185.  
  186.     CELIJA *top_row = (CELIJA *)malloc(n * sizeof(CELIJA));
  187.     CELIJA *bottom_row = (CELIJA *)malloc(n * sizeof(CELIJA));
  188.  
  189.     CELIJA **matrix = allocateMatrix(m, n);
  190.     setMatrixData(matrix, m, n);
  191.  
  192.     MPI_Init(&argc, &argv);
  193.  
  194.     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  195.     MPI_Comm_size(MPI_COMM_WORLD, &size);
  196.  
  197.     // Find submatrix for process
  198.     int startM = (rank * (m / size));
  199.     int endM = startM + (m / size) - 1;
  200.  
  201.     for (i = 0; i < steps; i++)
  202.     {
  203.         doWork(matrix, startM, endM, n);
  204.  
  205.         // upper cells
  206.         if (rank != 0)
  207.         {
  208.             MPI_Send(matrix[startM], n * 2, MPI_INT, rank - 1, 40, MPI_COMM_WORLD);
  209.             MPI_Recv(bottom_row, n * 2, MPI_INT, rank - 1, 40, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  210.  
  211.             doWorkEdge(matrix, bottom_row, n, startM);
  212.         }
  213.         // lower cells
  214.         if (rank != size - 1)
  215.         {
  216.             MPI_Send(matrix[endM], n * 2, MPI_INT, rank + 1, 40, MPI_COMM_WORLD);
  217.             MPI_Recv(bottom_row, n * 2, MPI_INT, rank + 1, 40, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  218.        
  219.             doWorkEdge(matrix, bottom_row, n, startM);
  220.         }
  221.     }
  222.  
  223.     // Find the strongest cancer cell
  224.     CELIJA strongest = findLocalStrongestCancerCell(matrix, startM, endM, n);
  225.  
  226.     MPI_Reduce(&strongest.jacina, &strongestGlobal.jacina, 1, MPI_INT, MPI_MAX, 0, MPI_COMM_WORLD);
  227.  
  228.     printf("[%d]: Strongest local: %d_%d\n", rank, strongest.tip, strongest.jacina);
  229.  
  230.     if (rank == 0) printf("Strongest global: %d\n", strongestGlobal.jacina);
  231.  
  232.     MPI_Finalize();
  233.  
  234.     return 0;
  235. }
Add Comment
Please, Sign In to add comment