Informatică, întrebare adresată de AfloareiAndrei, 8 ani în urmă

Am o nelamurire in legatura cu urmatorul program scris in c++.
In poza este vorba depre, generarea permutarilor folosind metoda backtracking.
Ce nu inteleg este de ce se intoarce 'k' la o valoare anterioara.
Ex:
Daca n = 3, atunci x1[] se va modifica la x1[1], x1[2], x1[3]
x1[1] x1[2] x1[3]
0 0 0 asa arata lista initial la indexurile 1, 2, 3 (celelalte valori din x1 vor
ramane 0).
1 0 0 k = 1;
1 1 0 k = 2;
1 2 0 k = 2;
1 2 1 k = 3;
1 2 2 k = 3;
1 2 3 k = 3; acum se va apela functia Afisare()
bucla din BackRec1 se opreste pentru ca i == n1
dar programul merge mai departe si eu nu inteleg de ce
poate sa imi explice cineva de ce?
asa va arata lista daca continuam
1 3 3 k = 2;
1 3 2 k = 3;
.........................................

Anexe:

Răspunsuri la întrebare

Răspuns de StarBack
1

Răspuns:

Hai că încerc să iți explic cât mai ușor ca să înțelegi.

Variabila „k” este de fapt nivelul stivei cu care lucrezi. Primele soluții iți sunt logice, așa că voi trece direct la cazul (1,2,3) care este prima soluție generată de algoritmul tău.

Suntem în cazul în care k = 3, după afișarea soluției (1,2,3) se caută în continuare pentru un succesor și nu se respectă condiția pentru că succesorul lui 3 este 4, prin urmare nivelul stivei scade cu o unitate ( k = 2 ). De aici se caută succesor pentru x1[2] (care este 1) și îl face 3, deci avem permutarea (1,3,3). Permutarea aceasta nu respectă condiția de valid care ne impune să nu avem elemente identice în permutare. Prin urmare se reapelează funcția, deci nivelul stivei crește cu o unitate ( BackRec1(k + 1) ).

Funcția se va apela dinou, și se inițializează elementul de pe nivelul 3 cu 1 (x1[3] = 1), deci avem permutarea (1,3,1). Permutarea nu este validă datorită funcției Valid (avem două elemente identice), se caută succesor și îl va inițializa pe x1[3] cu 2, deci avem permutarea (1,3,2), care respectă și condiția de soluție și afișează soluția (1,3,2). După soluția aceasta k va fi 1 și soluția imediat următoare după (1,3,2) este (2,1,3), iar apoi iar se repetă ce am făcut anterior și se obține (2,3,1) ș.a.m.d.

Ca să îți răspund la întrebarea ta mai pe scurt. Nivelul stivei scade ( adică „k” )dacă nu se respectă condiția de Succesor (adică acea structură repetitivă de la 1 la n).

Poate că înțelegi mai bine dacă ai face mai întâi varianta iterativă decât cea recursivă.

În cazul în care mai ai nelămuriri în legătură cu backtracking nu ezita să mă contactezi.

Îți doresc mult succes în continuare!


AfloareiAndrei: "Suntem în cazul în care k = 3, după afișarea soluției (1,2,3) se caută în continuare pentru un succesor și nu se respectă condiția pentru că succesorul lui 3 este 4, prin urmare nivelul stivei scade cu o unitate ( k = 2 )."
AfloareiAndrei: De ce scade pentru ca nu vad nicaieri 'k--'
AfloareiAndrei: asta nu inteleg. Si inca un exemplu. in functia BackRec1 dupa ce se apeleaza functia Afisare() i=3 (3 este valoarea maxima pe care o poate avea i in bucla aia) asta inseamna ca atunci cand ajung la finalul buclei i=4 si se opreste bucla. dar i o sa ia valoarea 2. am sa incerc sa nu folosesc o functie recursiva dar ma tem ca nu o sa imi iasa pentru ca ma scoate din minti 'k'-ul ala. :|
AfloareiAndrei: Acum stiu de ce nu intelegeam. Nu am folosit niciodata o bucla intr-o functie recursiva. Si am obsercat ca daca folosesc o bucla intr-o functie recursiva functia se reapeleaza in interiorul buclei deci in bucla initiala o sa apara o noua functie cu valori noi care are o bucla similara cu prima. Trebuie sa ma mai joc putin cu asta ca sa o inteleg mai bine.
AfloareiAndrei: Deci pe scurt functia BackRec1 nu se reapeleaza pe ea ci face apel la o functie BackRec1' care la randul ei apeleaza o alta functie BackRec1''... cand functia BackRec1'' ajunge sa apeleze functia Afiseaza()'', BackRec1' continua de unde a ramas pana apeleaza si ea Afiseaza()' in final BackRec1 continua de unde a ramas pana la apelul functiei Afiseaza()
AfloareiAndrei: Asta inseamna ca variabila 'k' nu scade; doar continua de unde a ramas bucla anterioara.
StarBack: Segmentul de stivă pus la dispoziție prin apelul functiei este gestionat în mod automat de sistem. Revenirea la pasul precedent se realizează în mod natural prin inchiderea nivelului de stivă.
Adică dacă nu mai există nici un element neselectat in multimea S = {1,2,3}, se inchide nivelul de stivă și astfel se revine pe poziția k-1 a vectorului.
AfloareiAndrei: De raspunsul asta aveam nevoie. Il poti pune ca un raspuns nou daca vrei si il selectez "Cel mai bun raspuns". Multumesc!
Alte întrebări interesante