МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
КАФЕДРА ЕЛЕКТРОННИХ ОБЧИСЛЮВАЛЬНИХ МАШИН
Лабораторна робота №3
з курсу “Паралельні та розподілені обчислення”
на тему: “Можливості використання паралельних алгоритмів”
Мета роботи: дослідити можливості розв’язання різноманітних задач за
допомогою паралельних алгоритмів. Навчитися виділяти незалежні гілки обчислень та виконувати їх паралельно.
Завдання:
5. Запропонувати та відобразити алгоритм реалізації гри “LIFE”. Гра моделює життя деякої колонії живих клітин, які виживають, розмножуються або гинуть згідно наступних умов. Клітина виживає, якщо вона має двох або трьох сусідів з восьми можливих. Якщо у клітини лише один сусід, або немає жодного, то вона гине (від ізоляції). Якщо клітина має більше трьох сусідів, то вона гине (від перенаселення). В будь-якій порожній позиції, яка має рівно трьох сусідів у наступному поколінні з’являється нова клітина. Гра повинна починатися з довільної кількості клітин, що розташовані в ігровому полі випадковим чином (інтерактивний режим задавання вхідних даних) – так звана початкова популяція. Програма повинна коректно завершувати роботу у таких випадках: а) загинула вся популяція, б) на вимогу користувача.
Виконання роботи:
Текст програми (з одноразовим присвоєнням):
/* file Lab2odn.cpp */
#include "stdio.h"
#include "stdlib.h"
#include "conio.h"
int **inp_mtx (int);
void rand_mtx (int **, int, int);
void out_mtx (int, int **);
void f_out_mtx (FILE *, int, int **);
void main ()
{
int n, ch, ch1, a, b, i, j, x, it=0;
int alive=0, neighbors=0;
int **coloniya;
FILE *fptr;
if ((fptr = fopen("rezult.txt", "w"))==NULL)
{ printf("\nNe mozhu vidkryty fajl");
exit(1); }
printf ("Vvedit rozmir colonii\n");
printf ("rozmir = ");
scanf ("%d", &n);
coloniya=inp_mtx (n);
printf ("--------------------------------------\n");
printf ("\nVvedit sposib zadannya kolonii:\n");
printf (" Vruchnu - natysnit 1\n");
printf (" Avtomatychno - natysnit 0\n");
printf ("Zrobit vybir [1/0]... ");
scanf ("%d", &ch);
printf ("--------------------------------------\n");
if (!ch)
{ printf ("\nVvedit bud-yake chyslo vid %d do %d: ", n+10, n*n);
scanf ("%d", &x);
rand_mtx (coloniya, n, x); }
else
{ printf ("\nVvedit pozycii, de budut znahodytys klityny\n");
printf ("(napryklad: 3 3, 7 1, 2 5...)\n");
while (ch!='n')
{ scanf ("%d%d", &a, &b);
coloniya[a][b]=1;
alive++;
printf ("continue? [y/n] ");
ch=getche ();
printf ("\n"); }
}
printf ("--------------------------------------\n");
printf ("\nPochatkova koloniya\n");
out_mtx (n, coloniya);
printf ("--------------------------------------\n\n");
getch();
alive=0;
do
{ alive=0;
for (i=1; i<=n; i++)
{ for (j=1; j<=n; j++)
{ if (coloniya[i-1][j]==1)
neighbors++;
if (coloniya[i-1][j+1]==1)
neighbors++;
if (coloniya[i][j+1])
neighbors++;
if (coloniya[i+1][j+1]==1)
neighbors++;
if (coloniya[i+1][j])
neighbors++;
if (coloniya[i+1][j-1]==1)
neighbors++;
if (coloniya[i][j-1])
neighbors++;
if (coloniya[i-1][j-1]==1)
neighbors++;
if (coloniya[i][j])
{ if (neighbors<=1)
coloniya[i][j]=0;
if (neighbors>3)
coloniya[i][j]=0;
if ((neighbors==2)||(neighbors==3))
coloniya[i][j]=1;
}
else
{ if (neighbors==3)
coloniya[i][j]=1;
else coloniya[i][j]=0;
}
if (coloniya[i][j])
alive++;
fprintf (fptr, "i=%d j=%d neighbors=%d alive=%d\n", i, j,
neighbors, alive);
f_out_mtx (fptr, n, coloniya);
neighbors=0;
}
}
it++;
out_mtx (n, coloniya);
printf ("Iteraciya %d, kilkist zhyvyh klityn %d\n", it, alive);
printf ("--------------------------------------\n\n");
fprintf (fptr, "Iteraciya %d, kilkist zhyvyh klityn %d\n", it, alive);
fprintf (fptr, "--------------------------------------\n\n");
ch1=getch();
if (ch1=='e')
break;
}
while (alive!=0);
printf ("Vyhid z programy\n");
fclose (fptr);
}
/********************** Funkcii *******************************/
int **inp_mtx (int rozm)
{
int i, **m;
m=(int**)calloc((rozm+2),sizeof(int*));
for (i=0; i<(rozm+2); i++)
m[i]=(int*)calloc((rozm+2),sizeof(int));
return m;
}
void out_mtx (int rozm, int **m)
{
int i, j;
for (i=1; i<=rozm; i++)
{
for(j=1; j<=rozm; j++)
printf("%3d ",m[i][j]);
printf("\n\n");
}
printf("\n");
}
void f_out_mtx (FILE *fp, int rozm, int **m)
{
int i, j;
for (i=1; i<=rozm; i++)
{
for(j=1; j<=rozm; j++)
fprintf (fp, "%3d ",m[i][j]);
fprintf (fp, "\n\n");
}
fprintf (fp, "\n");
}
void rand_mtx (int **mtx, int rozm, int max)
{ int i;
for (i=0; i<max; i++)
mtx[1+rand()/(RAND_MAX/rozm)][1+rand()/(RAND_MAX/rozm)]=1;
}
Після аналізу завдання в ньому можна виділити гілки: задання початкової колонії, обчислення поточного елементу, вивід колонії. Виділивши ці гілки, оформляємо їх як окремі функції і використовуємо в програмі.
Крім того, з метою півищення продуктивності, можна також реалізувати одночасний перегляд матриці з різних сторін (наприклад, з першого елемента і з останнього елемента).
Висновки: на цій лабораторній роботі я застосував паралельне представлення алгоритмів. Створена мною програма використовує такий спосіб паралелізму, як розбиття задачі на підзадачі, а також демонструє можливість використання паралельних обчислень.