Sunteți pe pagina 1din 3

Prof.

Miana Arișanu

Algoritmul lui Lee


Indicatoarele pot face dintr-o cale dreaptă un labirint
Stanislaw Jerzy Lec

Algoritmul lui Lee este folosit pentru determinarea unui traseu de lungime minimă într-un
labirint între două celule stabilite.
Haideți să-l ajutăm pe șoricel să ajungă la brânză!

1 2 3 4  În labirint există obstacole


1  Șoricelul nu poate ieși din labirint și se poate deplasa sus, jos,
 stânga sau dreapta, dacă nu este obstacol.
2
 Labirintul va fi memorat printr-o matrice cu n linii (numerotate de
3
la 1 la n) și m coloane (numerotate de la 1 la m)
4
5   In matrice, vom marca cu -1 obstacolele și cu 0 zonele libere

0 1 2 3 4 5  Pentru a verifica mai ușor dacă șoricelul iese din labirint,


0 bordăm matricea cu obstacole (liniile 0 și n+1, coloanele 0 și m+1)
1  Pentru a determina mai ușor noua poziție a șoricelului în
2  funcție de poziția curentă (linia l și coloana c) și de direcția de
3 deplasare (sus, dreapta, jos sau stânga), folosim vectorii
4 int dx[]= {-1,0,1, 0}, dy[]= {0, 1,0,-1};
5  Astfel nouă poziție va fi l+dx, c+dy
6

0 1 2 3 4 5  Poziția inițială a șoricelului va fi marcată în matrice cu


0 valoarea 1
1 2 4  Celulele vecine, libere, în care se poate ajunge din poziția
2 2 1 2 3 inițială vor fi marcate cu 2
3 3 2 3 Continuăm marcarea celulelor în matrice fie până ne blocăm fie
4 3 4 5 pănă ajungem la brânză. Astfel analizăm celulele marcate cu k și
5 5 4 5 6 marcăm cu k+1 toate celulele vecinelor care sunt libere
6  Problema nu are întotdeaună o soluție, iar dacă există soluție,
putem avem mai multe trasee cu număr minim de pași

Pentru a reține
int a[177][177]; // n<=175, adaugăm 2 pentru bordare
int cx[31000],cy[31000];
int dx[]= {-1,0,1, 0};
int dy[]= {0, 1,0,-1};
Prof. Miana Arișanu

f>>n>>nr_obstacole; //citirea datelor de intrare


for(i=1; i<=nr_obstacole; i++)
{
f>>x>>y;
a[x][y]=-1;
}
f>>x1>>y1; // poziția șoricelului
f>>x2>>y2; // poziția unde se află brânza

for(j=0; j<=n+1; j++) a[0][j]=a[n+1][j]=-1; // bordăm matricea cu -1


for(i=1; i<=n; i++) a[i][0]=a[i][n+1]=-1;

a[x1][y1]=1; //marcăm în matrice celula de start cu 1


cx[1]=x1; // adăugam în coada celula de start
cy[1]=y1;
p=u=1; // celula de start este și primul și ultimul element din coada
while (p<=u) // analizam celulele din coada
{
l=cx[p]; // l reprezinta linia celulei curente din coada
c=cy[p]; // c reprezinta coloana celulei curente din coada
for (k=0; k<=3; k++) // verific cei 4 vecini ai celulei curente
if (a[l+dx[k]][c+dy[k]]==0) // dacă vecinul e liber
{
a[l+dx[k]][c+dy[k]]=a[l][c]+1;
u++;
cx[u]=l+dx[k];
cy[u]=c+dy[k];
if (cx[u]==x2 && cy[u]==y2) // dacă am ajuns la brânză
break;
}
p++;
}

if (a[x2][y2]==0) cout<<”nu avem solutie”;


else
{
g<<a[x2][y2] <<” celule de la pozitia initială la poziția finală”;
drum (x2,y2);
}
Prof. Miana Arișanu

void drum (int l, int c) // afișează un drum de lungime minimă de la (x1,y1) la (l,c)
{
if (l!=x1 || c!=y1)
if (a[l-1][c]==a[l][c]-1) drum (l-1,c);
else
if (a[l+1][c]==a[l][c]-1) drum (l+1,c);
else
if (a[l][c-1]==a[l][c]-1) drum (l,c-1);
else drum (l, c+1);
cout<<l<<’ ‘<<c<<’\n’;
}

Observații finale

1. https://www.pbinfo.ro/probleme/2167/alee
2. Dacă există, drumul nu e unic, poate fi reconstituit pornind de la pozitia finala
3. Algoritmul lui Lee poate fi implementat și 3D, atunci când labirintul este într-un
paralelipiped https://www.infoarena.ro/problema/traseu3
4. O implementare mai eficientă a algoritmului lui Lee utilizează containerul queue din
STL

S-ar putea să vă placă și