Sunteți pe pagina 1din 41

Metode de rezolvare a problemelor

– căutare în spațiul soluțiilor


Spațiul soluțiilor
••   Fie mulțimile , , o relație de ordine pe

• spațiul soluțiilor

• funcție de validare

• mulțimea soluțiilor rezultat

• funcții de validare parțială

• se poate adăuga un element cu .


Backtracking
(metoda căutarii cu revenire)
Backtracking – căutare completă

• Metodă lentă, costisitoare, complexitate mare
  – Verificarea (aproape a) tuturor elementelor spațiului soluțiilor

• ,
• pt. fiecare element al solutiei este definita multimea valorilor posibile
,

– - condiții de continuare

• se construiește element cu element


– primește o valoare din numai după toate elementele anterioare ()
– se trece la elementul
• altfel se alege altă valoare pentru
– valoarea aleasă pentru e consumată mulțimea valorilor consumate
• dacă nu mai sînt valori disponibile se revine la elementul anterior
– nu garantează obținerea unei soluții
Backtracking
A. Probleme
• 1.Generarea tuturor permutărilor
• 2.Generarea tuturor submultimilor unei multimi
• 3.Problema colorării hărților
• 4.Problema fotografiei
• 5.Problema investitorului*

B. Intrebari
1.Generarea tuturor permutărilor
1.Generarea tuturor permutărilor

Enunt: Realizați generarea tuturor permutărilor de


n elemente (pentru n=4).
• Pas 1: Se utilizează un vector v cu 4 elemente.
v[i] : elementul de pe poziţia i din permutare
ex: v[2]=1 pe pozitia 2 se afla elementul cu valoarea
1
1.Generarea tuturor permutărilor
• Pas 2: Se completeză vectorul v de la stânga la
dreapta cu valori succesive de la 1 la n.
1.Generarea tuturor permutărilor
1.Generarea tuturor permutărilor
1.Generarea tuturor permutărilor
• Pas 3:
– Dintre candidati se aleg solutiile
– Solutii = formele vectorului care indeplinesc conditiile problemei
– Condiţia problemei = este ca toate elementele vectorului să fie
completate şi diferite între ele.

• Pas 4:
– Algoritmul se repetă până când nu se mai îndeplineşte condiţia:
indexul k al vectorului >0 (stiva este goală).
1.Generarea tuturor permutărilor

• Exemplu de rulare pentru n=3


1.Generarea tuturor permutărilor
• #include<stdio.h> //afisare solutie pe ecran
• #include<conio.h> //I: numarul solutiei ( num), dimensiunea
• char r='n'; permutarii( nr), permutarea(v)
•   void retine_solutia (int num, int nr,int *v)
{int i;
• //verifica daca valoarea
 
elementului i este acceptabila printf("\n\n Solutia numarului %d\n", num);
(diferita de cele anterioare) for (i=0;i<nr;i++)
• int posibil(int *v, int i) printf("%2d ", v[i]);
• {
• int j,r; if (r=='n')
• { printf("\n\nUrmatoarea solutie (n) sau
r=1;
Ultima (l) ?");
• for(j=0;j<i;j++) r=_getch();
• if(v[i]==v[j]) }
• r=0; }
• return r;
• }
1.Generarea tuturor permutărilor
• //genereaza permutari de n elemente (1..n)
• //I:n
• //E: numar permutari
• int permutari (int n)
• {
• int *p, i, am, nr;
• //pentru ca se foloseste un vector de dimensiune n, cu indici de la 0 la n-1 (in loc de 1..n)
• //indicele i arata o configuratie solutie daca i==n, confimguratie dinala daca i=-1

• p=new int[n]; //vector solutie
• nr=0; //numar solutii
• i=0;
• p[0]=0; //prima valoarea minus ratia
• while (i>=0) //cat timp nu am ajuns la configuratia finala)
• { am=0;
• while (p[i]<n && !am) //alege urmatoarea valoarea acceptabila pentru x[i]
• { p[i]++;
• am=posibil (p,i); //este acceptabila?
• }

• if (!am) //impas, revenire
• i--;
• else
• if (i==n-1) //configuratie solutie
• retine_solutia(++nr,n,p);
• else
• p[++i]=0; //prima valoarea minus ratia
• }
• delete p;
• return nr;
• }
1.Generarea tuturor permutărilor

• void main()
• { int n, perm;
• printf("Dati n=");
• scanf("%d",&n);
• perm=permutari(n);
• }
2.Generarea tuturor submultimilor unei
multimi
2.Generarea tuturor submultimilor unei multimi.

Enunt: Fie un numar natural nenul n. Sa se scrie


programul C de generare a tuturor submultimilor
multimii {1, 2, 3,..., n}.

EXEMPLU:
Pentru n=3 programul va genera
{}
{1} {2} {3}
{1,2} {1,3} {2,3}
{1,2,3}
 
2.Generarea tuturor submultimilor unei multimi.

SOLUTIE:
 Solutia x[1]......x[n],
unde x[i] poate fi 0 (i nu apartine submultimii) sau 1 (i apartine submultimii)

 Solutia Codificare
{} 000
{3} 001
{2} 010
{2,3} 011
{1} 100
{1,3} 101
{1,2} 110
{1,2,3} 111
 
Obs: x[k] poate fi 0 sau 1
2.Generarea tuturor submultimilor unei
multimi
• #include <conio.h> • void BackRec(int k)
• #include<stdio.h> • { int i;
•   • for(i=0;i<=1;i++)
•   • { x[k]=i;
• char sp[]=" "; • if (k==n) Afisare();
•  
• else BackRec(k+1);
• int x[20], n, nrsol=0;
• }
•  
• }
• void Afisare()
• { int i;
• printf("%c {",sp); //cout<<sp<<"{ ";
• for(i=1;i<=n;i++)
• if (x[i]==1) printf ("%d ",i); //cout<<i<<" ";
• printf (" }\n");//cout<<char(8)<<"}"<<endl;
• nrsol++;
• //if (nrsol%22==0) _getch();//cin.get();
• }
2.Generarea tuturor submultimilor unei
multimi
• int main()
• { printf ("\n\nSubmultimile multimii {1,2,3.....,n}\n ");
//cout<<endl<<endl<<sp<<"Submultimile multimii {1,2,3.....,n}"<<endl;
• printf(" Dati valoarea unui n:");
• scanf("%d", &n); //cout<<endl<<sp<<" Dati valoarea lui n: "; cin>>n;
• printf("\n"); //cout<<endl;
• BackRec(1);
• printf("Nr. solutii: %d\n", nrsol); //cout<<endl<<sp<<"Numar solutii:
"<<nrsol;
• _getch();
• return 0;
• }
•  
3.Problema colorării hărților
3.Problema colorării hărților
• Enunt: Fiind data o harta cu n tari, se cer toate
solutiile de colorare a hartii, utilizand cel mult
patru culori, astfel incat doua tari ce au
frontiera comuna sa fie colorate diferit. Este
demonstrat faptul ca sunt suficiente numai
patru culori pentru ca orice harta sa poata fi
colorata.
3.Problema colorării hărților
• Exemplu de fisier pentru matrice:
Exemplu de rulare

A B C D
A0 1 0 1
B1 0 1 1
C0 1 0 1
D1 1 1 0
3.Problema colorării hărților
• #include<stdio.h> • void tipar()
• #include<conio.h>
• #include<math.h> • {for(int i=1;i<=n;i++)
• int st[20],n,k,a[20][20]; • printf ("Tara numarul %d ce are culoarea
•  
• void init()
%d\n", i,st[i]);
• {st[k]=0;} • printf("\n\n");
•   • }
• int succesor()
• {if (st[k]<4)
•  
• {st[k]++; • void bkt()
• return 1; • {int as;k=1;
• }
• else return 0;} • init();
•   • while(k>0)


int valid()
• {
{for(int i=1;i<k;i++)
• if(st[i]==st[k] && a[i][k]==1) return 0; • do {} while ((as=succesor()) && !valid());
• return 1;} • if (as)
•  
• int sol()
• if (sol()) tipar();
• {return (k==n);} • else {k++;init();}
• else k--;
• } }
3.Problema colorării hărților
• void main()
• { printf("Dati numarul de tari:");
• scanf ("%d", &n);
• printf("Dati matricea:\n");
• for(int i=1;i<=n;i++)
• for(int j=1;j<=n;j++) scanf ("%d",&a[i][j]);
• bkt();
• _getch();
• }
4.Problema fotografiei
4.Problema fotografiei
Enunt (varianta a problemei colorarii hartilor):
O fotografie alb–negru este reprezentata sub
forma une matrice binare. Ea infatiseaza 1 sau mai
multe obiecte. Portiuni corespunzatoare obiectelor
se reprezinta in matrice prin valoarea 1, iar cele
corespunzatoare fundalului prin valoarea 0.
• Se cere sa se determine numarul de obiecte
nObiecte si sa se coloreze obiectele cu culori
diferite: 2,3,nObiecte+1.
4.Problema fotografiei
• Doua puncte in folografie care au valoarea 1 apartin aceluiasi obiect
daca ele sunt vecine pe linie sau coloana. Pentru rulare, fotografia alb-
negru este prezentata in fisierul “in.txt”, conform datelor de mai jos:
45
11011
00010
11011
10110

Rezultatul este cel din figura (continutul fisierului foto_out.txt):


4.Problema fotografiei
• Biblioteci: In main:
{ -se declara si se deschid fisierele (FILE *fin =
• Declarari de tip intreg: a[20][20],m,n; fopen("in.txt","r"); FILE *fout = fopen ("foto_out.txt", "w"); )
• void coloreaza (int i, int j, int cul) -se declara intregi: i,j,cul;
• daca (fin) fscanf (fin,"%d %d", &m, &n);
{
for (i=0;i<m;i++)
• daca for (j=0;j<n;j++)
• (0<=i && i<m && 0<=j && j<n && fscanf(fin,"%d", &a[i][j]);
cul=1;
1==a[i][j])
for (i=0;i<m;i++)
• { for (j=0;j<n;j++)
• a[i][j] = cul; daca (1==a[i][j]) coloreaza(i,j, ++cul);
fprintf(fout, "%d",--cul);
• coloreaza(i, j-1, cul); for (i=0;i<m; i++)
• coloreaza(i, j+1, cul); {
fprintf(fout, "\n");
• coloreaza(i-1, j, cul); for(j=0;j<n;j++)
• coloreaza(i+1, j, cul); fprintf(fout, "%d", a[i][j]);
• } }
-Se inchid fisierele fin si fout;
• } }
5.Problema investitorului
5.Problema investitorului
Enunt: Un investitor, care dispune de un capital C,
pe care dorește sa-l investească in vederea obținerii
unui profit, va proceda in felul următor:
• va alege
– dintre n oferte la care trebuie avansate fondurile fi
– si care aduc beneficiile bi
• pe acelea pe care le poate onora cu capitalul de
care dispune si care-i aduc beneficiul maxim
5.Problema investitorului
Soluție:
• O soluție a problemei poate fi reprezentata printr-o selecție de
oferte:
• (s1, s2, …, sn)
• in care si = 1 sau si = 0 după cum oferta a fost sau nu considerata de
investitor.

• Soluțiile acestei probleme au mereu aceeași lungime n. Condiția s i є


{0,1}, cunoscuta si sub numele de restricție explicita, definește un
spațiu al soluțiilor posibile de dimensiune 2 n .
• Condiția ca suma investita sa nu depășească capitalul definește o
funcție de limitare sau o restricție implicita, care restrânge numărul
soluțiilor.
5.Problema investitorului
Prezentarea metodei
• În metoda căutării cu revenire, soluția este construită în
mod progresiv, prin adăugarea cîte unei componente sp+1 la
o soluție parțială (s1,s2,...,sp) care reprezintă o selecţie din
primele p oferte din totalul celor n , astfel încît (s1,...,sp+1) să
reprezinte de asemeni o soluţie parţială. Soluţia parțială
mai poate fi întâlnită şi sub numele de soluţie p-realizabilă.
• O soluţie finală este obţinută în momentul în care a fost
făcută o selecţie dintre cele n oferte. Aceasta este
comparată cu soluţia optimă determinată până acum, fiind
reţinută sau ignorată.
5.Problema investitorului
Astfel în cazul concret în care: n=3, C=5000 și
  1 2 3
f1 2000 2200 2500
b1 300 400 500

investitorul adoptă următoarea strategie: pentru fiecare ofertă dezvoltă o


soluţie acceptând oferta, şi pe o alta respingând-o.
5.Problema investitorului
Acceptarea ofertei 1 (s1=1) este posibilă deoarece investiţia totală ar fi numai 2000, iar
beneficiul 300;
• Dacă se acceptă şi oferta 2 (s2=1), investiţia 4200 aduce profitul 700, acceptarea
ofertei 3 nu mai este posibilă deoarece investiţia totală ar fi 6700, depăşind capitalul,
deci oferta 3 va fi respinsă (s3=0); fiind considerate toate ofertele s-a obţinut o soluţie
(1,1,0) cu investiţie totală 4200 şi profit 700, aceasta este deocamdată reţinută ca
soluţie optimă.
• Dacă nu se acceptă oferta 2 (s2=0) se poate accepta oferta 3 (s3=1) deoarece se face o
investiţie totală de 4500 şi se obţine profitul 800. Soluția (1,0,1) este mai bună ca
soluţia optimă curentă, fiind reţinută. Soluţia (1,0,0), obţinută prin ignorarea ofertei
3, presupune investiţia totală 2000 şi aduce profitul 300, mai mic decât cel din soluţia
aleasă anterior ca optimă, motiv pentru care nu este reţinută.
• Dacă se ignoră oferta 1 (s1=0), acceptarea ofertei 2 şi a ofertei 3 duce la o investiţie
4700 şi profit 900, reprezentând cea mai bună soluţie. Toate aceste situaţii sunt
reprezentate în Figura 1.
5.Problema investitorului
i=0
s1 = 1 s1 = 0
pr = 0

i = 2000 i=0
s2 = 0 s2 = 1 s2 = 0
pr = 300 pr = 0
s2 = 1

i = 4200 i = 2000 i = 2200 i=0


pr = 700 pr = 300 pr = 400 pr = 0
s3 = 1 s3 = 0 s3 = 1 s3 = 0
s3 = 1 s3 = 0 s3 = 1 s3 = 0

i = 4200 i = 4500 i = 2000 i = 4700 i = 2200 i = 2500 i=0


i = 6700
pr = 700 pr = 800 pr = 300 pr = 900 pr = 400 pr = 500 pr = 0
5.Problema investitorului
• Se observă că spațiul soluţiilor problemei se poate reprezenta ca un arbore - arborele
spațiului stărilor (ASS). Fiecare nod din arbore defineşte o stare soluţiilor problemei;
nodurile interne fiind soluții parţiale, iar nodurile frunze - soluţii finale.
• De exemplu, în problema investitorului, fiecare nod din arbore corespunde unei decizii
de acceptare sau de respingere a unei oferte; nodul rădăcină va reprezenta situaţia
iniţială, în care nu a fost considerată încă nici o ofertă. Acest nod va avea 2 succesori,
corespunzând acceptării sau respingerii primei oferte, subarborii fiecărui nod de pe
nivelul p corespund acceptării sau respingerii ofertei p. Înălţimea arborelui spaţiului
stărilor este deci n+1.
• Metoda căutării cu revenire constă în generarea sistematică de noduri stări ale soluţiei
problemei, pornind de la nodul rădăcină şi selectarea dintre acestea a nodurilor soluții.
In parcurgerea arborelui spaţiului stărilor se va lua în considerare o listă de noduri
active - noduri la care nu s-au generat încă toţi succesorii direcţi.
• Funcţiile de limitare reduc numărul nodurilor active fără a le genera toţi urmașii; se
minimizează astfel procesul de căutare prin detectarea și evitarea căilor care nu conduc
la soluții.
Alte probleme
• Să
  se genereze toate aranjamentele dintr-o
mulțime cu elemente, luate cîte .
• Să se genereze toate combinările dintr-o
mulțime cu elemente, luate cîte .
• Plata unei sume (cu/fără bancnotă unitate). Fie
tipuri de bancnote, cu valorile nominale . Din
fiecare tip este disponibilă cantitatea . Să se
determine toate modalitățile în care se poate
plăti o sumă folosind aceste bancnote.
B. Intrebari ?
Spor la invatat !
Referinte bibliografice
• ATP – suport de curs si seminar
• * - Cristea, V., Athanasiu I., Kalisz E., Iorga V., Tehnici de programare, Editura Teora

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