Documente Academic
Documente Profesional
Documente Cultură
Atestat informatica
Algoritmul lui Lee
Cuprins
1. Consideraii teoretice
1.1 Motivarea alegerii temei 1.2 Conceptul algoritmului 1.3 Prezentarea algoritmului
1.3.1 Prezentarea algoritmului in pseudocod 1.3.2 Prezentarea algoritmului general in limbaj C++
2. Aplicaii practice
2.1 Problema Insule 2.2 Problema Alee
3. Bibliografie
1. Consideraii teoretice
1.1 Motivarea alegerii temei
Consider ca atat matricele cat si arborii sunt notiuni esentiale in informatica studiata in liceu. Astfel parcurgerea acestora determinand drumurile minime dintre doua puncte sau de iesire dintr-un tablou reprezinta probleme de natura importanta usor solutionate cu ajutorul algoritmului ales pentru studiu si anume algoritmul lui Lee. Matricele dupa cum bine stim sunt in informatica tablouri bidimensionale de variabile. Algoritmul lui Lee isi propune rezolvarea problemelor de orientare intr-un labirint aceasta fiind matricea. In esenta algoritmul poate fi aplicat pentru rezolvarea mai multor tipuri de probleme: - descoperirea drumului minim dintr-o matrice de la un punct dat a(u,v) la alt punct b(g,c), unde u, v, g si c sunt coordonatele punctelor din matrice introduse de la tastatura. - descoperirea posibilitatii de iesire dintr-o matrice labirint. Fiind pozitionat pe un punct din matrice de coordinate (i,j) algoritmul va determina daca este posibil sau nu parasirea matricei, deplasarea facandu-se pe punctele din matrice de valori diferite de 0. - descoperirea drumului de cost minim dintr-un arbore
Etapa 2 - Expansiunea Se repeta marcarea tuturor vecinilor neetichetati ai punctelor marcate cu i cu i+1 pana cand este atinsa tinta sau niciun punct nu poate fii marcat.
Etapa 3 - Refacerea drumului Ne pozitionam pe punctual tinta. Se repeta: - pozitionarea pe urmatorul nod ce are un marcaj mai mic decat nodul pe care suntem pozitionati - adaugarea acestuia la drum pana cand nodul de origine este atins.
Etapa 4 - Curatarea Blocam drumul pentru viitoare conexiuni. Se sterg toate marcajele
1.3.2 Prezentarea algoritmului in limbaj C++ pentru determinarea unui drum minim intr-o matrice
enun: Se consider o matrice ptratic de ordinul N n care avem o singura valoare nul la o poziie cunoscut, mai multe valori -1 cu rol de valoare inaccesibil i o valoare foarte mare n restul locaiilor. Se cere s se gseasc cel mai mic drum de la valoarea 0 ctre o alt locaie de asemenea cunoscut, diferit de locaiile inaccesibile. rezolvare: Algoritmul lui Lee marcheaz n matrice pasul 1 peste tot n jurul valorii 0 daca rmnem n matrice i dac nu se ntlnesc puncte inaccesibile. Se marcheaz cu pasul 2 n jurul tuturor valorilor 1 in aceleai condiii ca n pasul anterior. Altfel spus, aflndu-ne la un pas oarecare k analizm toi cei 4 vecini ai unei locaii curente si marcm cu pasul k+1, daca valoarea existent ntrun anumit vecin este diferit de -1, rmne n matrice, memoreaz o valoare mai mare decat k+1, adic se optimizeaz traseul de la locaia cu 0 ctre resspectivul(vecin).
#include<fstream> #include<iostream> #include<iomanip> #define N 100 using namespace std; void Lee(int a[][N],int m, int n, int l, int c, int pas){ if (l>1 && a[l-1][c]>pas+1) { a[l-1][c]=pas+1; Lee(a, m, n, l-1, c, pas+1); } if (c<n && a[l][c+1]>pas+1) { a[l][c+1]=pas+1; Lee(a,m,n,l,c+1,pas+1); } if (l<m && a[l+1][c]>pas+1){ a[l+1][c]=pas+1; Lee(a, m, n, l+1, c, pas+1); } if (c>0 && a[l][c-1]>pas+1){ a[l][c-1]=pas+1; Lee(a, m, n, l, c-1, pas+1); } } void tipar (int a[][N], int m, int n) { int i,j; for (i=1; i<=m; i++){ for (j=1; j<=n; j++) cout<<setw(5)<<a[i][j]; cout<<endl; } }
int main () { int a[N][N],l,c,lf,cf,m,n,i,j; fstream f("Lee.txt",ios::in); f>>m>>n; for (i=1; i<=m; i++) for (j=1; j<=n; j++) { f>>a[i][j]; if (a[i][j]==0){ l=i; c=j; } } cout<<"Dati lf si cf ";cin>>lf>>cf; if(a[lf][cf]==-1) return 0; Lee(a,m,n,l,c,0); if (a[lf][cf]==100) cout<<"Locatie inaccesibila"; else tipar(a,m,n); } Observaie: Algoritmul recursivitatea. prezentat folosete ca metod principal
2. Aplicaii practice
cerin: Dat fiind harta arhipelagului s se determine cte insule aparin fiecrei ri, precum i lungimea minim a unui pod care s satisfac condiiile din enunt. date de intrare: Fiierul de intrare insule.in conine pe prima linie numerele naturale N i M, separate prin spaiu. Pe urmtoarele n linii este descris harta arhipelagului. Pe fiecare dintre aceste n linii sunt scrise cte m valori din mulimea {0, 1,2, 3}; valorile nu sunt separate prin spaii. date de ieire: Fiierul de ieire insule.out va conine o singur linie pe care vor fi scrise patru numere naturale separate prin spaii NR NG NB Lg, unde NR reprezint numrul de insule aparinnd rii R, NG numrul de insule aparinnd rii G,NB numrul de insule aparinnd rii B, iar Lg lungimea minim a podului. restricii i precizri: 1 N,M 100 Se garanteaz c pe hart exist cel puin un element 1, un element 2 i un element 0. Se acord 40% din punctaj pentru determinarea corect a numrului de insule din fiecare ar; se acord punctaj integral pentru rezolvarea corect a tuturor cerinelor. nceputul i sfritul podului pot s coincid. Pentru datele de test exist ntotdeauna soluie.
10
codul surs al rezolvrii: #include<fstream> using namespace std; ifstream f("insule.in"); ofstream g("insule.out"); char c; int k, ok, o, mini, nr, x, y, n1, n2, n3, i, j, n, m, v[102][102], v1[102][102]; void fill(int x, int y, int k) { if(v1[x][y]==k) { v1[x][y]=4; fill(x-1,y,k); fill(x,y-1,k); fill(x+1,y,k); fill(x,y+1,k); } }
int main() { f>>n>>m; for(i=1; i<=n; i++) { f.get(c); for(j=1; j<=m; j++) { f.get(c); v1[i][j]=c-48; v[i][j]=v1[i][j]; if(v[i][j]==2) v[i][j]=-2; else if(v[i][j]==3) v[i][j]=-3; }
11
} n1=0; n2=0; n3=0; for(i=0; i<=n+1; i++) { v1[i][0]=4; v1[i][m+1]=4; v[i][0]=-4; v[i][m+1]=-44; } for(i=1; i<=m; i++) { v[0][i]=-4; v[n+1][i]=-4; v1[0][i]=4; v1[n+1][i]=4; } for(i=1; i<=n; i++) for(j=1; j<=m; j++) if(v1[i][j]==1) { n1++; fill(i,j,1); } else if(v1[i][j]==3) { n3++; fill(i,j,3); } else if(v1[i][j]==2) { n2++; fill(i,j,2); } g<<n1<<" "<<n2<<" "<<n3<<" "; mini=9999; k=1; ok=1; while(ok==1) {
12
ok=0; for(i=1; i<=n; i++) for(j=1; j<=m; j++) if(v[i][j]==k) { if(v[i][j+1]==0) { v[i][j+1]=k+1; ok=1; } if(v[i][j-1]==0) { v[i][j-1]=k+1; ok=1; } if(v[i+1][j]==0) { v[i+1][j]=k+1; ok=1; } if(v[i-1][j]==0) { v[i-1][j]=k+1; ok=1; } } k++; } mini=9999; for(i=1;i<=n;i++) for(j=1;j<=m;j++) if(v[i][j]==-2) { if(v[i][j+1]>1) if(v[i][j+1]<mini&&v[i][j+1]>1) mini=v[i][j+1]; if(v[i][j-1]>1) if(v[i][j-1]<mini&&v[i][j-1]>1) mini=v[i][j-1]; if(v[i+1][j]>1) if(v[i+1][j]<mini&&v[i+1][j]>1) mini=v[i+1][j]; if(v[i-1][j]>1) if(v[i-1][j]<mini&&v[i-1][j]>1) mini=v[i-1][j];
13
14
15
restricii i precizri: 1 N 175 1 M N*N Aleea este continua daca oricare doua placi consecutive au o latura comuna. Aleea incepe cu zona unde se gaseste prima poarta si se termina cu zona unde se gaseste cea de a doua poarta. Pozitiile portilor sunt distincte si corespund unor zone libere. Pentru datele de test exista intotdeauna solutie. codul surs al rezolvrii: #include<fstream.h> #define N 300 ifstream f("alee.in"); ofstream g("alee.out"); struct punct { int x; int y; } cd[N]; int a[177][177],p,nrelem; int dx[] = { -1, 0, 0, 1 }; int dy[] = { 0, -1, 1, 0 }; void init() { p=nrelem=0; } int vplin() { if(nrelem==N) return 1; return 0; }
16
int vgol() { if(nrelem==0) return 1; return 0; } int add(punct el) { if(vplin()==1) return 0; cd[(p+nrelem)%N]=el; nrelem++; return 1; } int extract(punct &el) { if(vgol()==1) return 0; el=cd[p]; p=(p+1)%N; nrelem--; return 1; } int main() { int i,n,m; punct c2,c1,a1,b1; f>>n>>m; for(i=0; i<=n+1; i++) a[0][i]=-1, a[n+1][i]=-1, a[i][0]=-1, a[i][n+1]=-1; for(; m; --m) { f>>a1.x>>a1.y; a[a1.x][a1.y]=-1; } f>>a1.x>>a1.y>>b1.x>>b1.y; a[a1.x][a1.y]=1;
17
init(); add(a1); while(vgol()==0) { extract(c1); for(i=0; i<4; i++) { c2.x=c1.x+dx[i]; c2.y=c1.y+dy[i]; if(a[c2.x][c2.y]==0) { a[c2.x][c2.y]=a[c1.x][c1.y]+1; add(c2); } } } g<<a[b1.x][b1.y]; f.close(); g.close(); return 0; }
18
III. Bibliografie
1. Boian F. M. De la arithmetic la calculatoare, Ed. Presa, Universitatea Clujean, Cluj-Napoca, 1996 2. Burdescu D. D. Tehnici de programare n Turbo C, Craiova 1995 3. Oltean M. Proiectarea i implementarea algoritmilor, Ed. Agora, Cluj-Napoca, 1999 4. Rancea D. Limbajul C++ - Algoritmi fundamentali, manual pentru clasa a XI-a, Ed. Agora, Cluj Napoca, 1999
19