Documente Academic
Documente Profesional
Documente Cultură
Laborator 5
Descriere: Divide et Impera
1. Introducere
Caracteristici:
• Nu toate problemele pot fi rezolvate prin folosirea acestei tehnici. Numărul problemelor
care pot fi rezolvate folosind tehnica Divide Et Impera este relativ mic, deoarece
descompunerea unei probleme (subprobleme) în subprobleme de aceeaşi natură este greu de
realizat
• Algoritmii Divide Et Impera se implementează de obicei într-o metodă recursivă, aceasta
fiind apelată recursiv pentru subproblemele create prin descompunere.
Algoritm:
O implementare generală a unui algoritm de tip Divide et Impera poate fi dată sub forma unei
metode recursive.
2. Pentru o situaţie diferită de cea de la punctul 1, problema se descompune în două sau mai
multe subprobleme notate P1, P2,… Pk, şi metoda este reapelată pentru fiecare dintre ele. În
final, se combină rezultatele şi se revine din apel.
ASD
2.1 Determinarea minimului într-un tablou de elemente întregi prin Divide et Impera
import java.io.*;
m1=min(s,j);
m2=min(j+1,d);
a=new int[nrElem];
Căutarea binară se poate aplica numai pentru tablouri ordonate în prealabil. Numită şi căutare
logaritmică sau căutare bisectoare, metoda împarte în mod repetat vectorul în doi vectori de
ASD
lungime egală, sau care diferă prin cel mult un element. Se compară apoi valoarea căutată k cu
valoarea elementului aflat la mijlocul vectorului. Ca rezultat al comparării se indică subvectorul în
care se va repeta procesul. Procesul continuă până când se ajunge la un vector de lungime 0 (dacă
valoarea căutată k nu a fost găsită) sau avem egalitatea a[m] == k unde m este indicele care
desparte cei doi vectori. Valoarea căutată va fi găsită, sau se va constata că lipseşte, după un număr
de cel mult log2n comparaţii, complexitatea algoritmului de căutare binară fiind O(log2n). Varianta
recursiva, specifica algoritmilor de tip Divide et Impera este urmatoarea
else {
if (a[j]<valoare)
return cautaRecursiv(valoare,j+1,d);
else return cautaRecursiv(valoare,s,j-1);
}
}
La acest algoritm de tip Divide Et Impera lipseşte etapa de combinare a soluţiilor subproblemelor,
soluţia finală fiind aleasă dintre soluţiile parţiale.
Se bazeaza pe metoda interschimbarii, ınsa interschimbarea se face pe distante mai mari. Astfel,
avand tabloul a[], se aplica urmatorul algoritm
In acel moment, tabloul a[] va fi partitionat ın 2 astfel, la stanga lui x se vor gasi elemente mai mici
ca si x, la dreapta, elemente mai mari ca si x. Dupa aceasta, se aplica acelasi proces subsirurilor de
la stanga si de la dreapta lui x, pana cand aceste subsiruri sunt suficient de mici (se reduc la
un singur element). Algoritmul este exemplificat grafic in figura 1
ASD
ASD
class QuickSort{
x=a[mijloc];
do{
while (a[i]<x) i++;
while (a[j]>x) --j;
//interschimbare
if(i<=j){
temp=a[i];
a[i]=a[j];
a[j]=temp;
j--;
i++;
}
}while(i<=j);
ASD
if(st<j) quickSort(st,j,a);
if(i<dr) quickSort(i,dr,a);
}// quickSort
}//class
Algoritmul de sortare MergeSort foloseşte strategia clasică a metodei Divide Et Impera. Un vector
cu n elemente este împărţit în doi subvectori cu câte n/2 elemente. Apoi se sortează cei doi vectori
şi soluţia finală se obţine prin interclasarea lor. Etapa de combinare a soluţiilor parţiale de la
metoda Divide Et Impera este reprezentată de interclasare. Sortarea subvectorilor se face tot prin
divizare şi interclasare, până când se ajunge la un vector de dimensiune 1.
else{
int mid = (s+d)/2; //mijlocul domeniului
}
}
Metoda de interclasare reuneşte secvenţele ordonate a[inf], ... ,a[mid] şi a[mid+1], ... , a[sup] mai
întăi în vectorul auxiliar temp, şi apoi copiază toate elementele acestuia în vectorul a. Interclasarea
a doi vectori ordonaţi se face prin compararea elementelor succesive din cei doi vectori: cel mai
mic dintre elementele comparate este copiat în vectorul rezultat şi se avansează în vectorul din care
acesta a fost copiat la următorul element. După ce toate elementele apaţinând unuia dintre cei doi
vectori au fost copiate, elementele rămase în celălalt vector sunt transferate în vectorul rezultat.
public void interclasare(int s, int m, int d, int [] temp){
while(m <= d)
temp[j++] = a[m++];
0 0 100 50
1
20 10
import java.io.*;
class PlacaGauri{
for(i=1;i<=n;i++){
st.nextToken(); x[i]=(int) st.nval;
st.nextToken(); y[i]=(int) st.nval;
}
dr(x1,y1,x2,y2);
out.println(amax);
out.println(x1s+" "+y1s+" "+x2s+" "+y2s);
out.close();
}
ASD
if(s<=amax) return;
boolean gasit=false;
for(i=1;i<=n;i++)
if((x1<x[i])&&(x[i]<x2)&&(y1<y[i])&&(y[i]<y2)){
gasit=true;
break;
}
if(gasit){
dr(x1,y1,x[i],y2);
dr(x[i],y1,x2,y2);
dr(x1,y[i],x2,y2);
dr(x1,y1,x2,y[i]);
}
else {
amax=s;
x1s=x1;
y1s=y1;
x2s=x2;
y2s=y2;
}
}
}
Se dau trei tije verticale A, B si C. Pe tija A se gasesc n discuri de diametre diferite, aranjate ın
ordine descrescatoare a diametrelor de la baza spre varf. Se cere sa se gaseasca o strategie de
mutare a discurilor de pe tija A pe tija C respectand urmatoarele reguli:
la un moment dat se va muta un singur disc (cel care se afla deasupra celorlalte discuri pe o
tija)
un disc poate fi asezat doar peste un disc de diametru mai mare decat al sau ori pe o tija
goala.
import java.io.*;
class Hanoi{
static int nrMutare=0;
int nrDiscuri;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Introduceti numarul discurilor: ");
nrDiscuri=Integer.parseInt(br.readLine());
solutiaHanoi(nrDiscuri, 'A', 'B', 'C');
}// main()
if(nrDiscuri==1)
System.out.println(++nrMutare + " Disc 1 " + tijaSursa + " ==> "+
tijaDestinatie);
else{
solutiaHanoi(nrDiscuri-1,tijaSursa,tijaDestinatie,tijaIntermediara);
System.out.println(++nrMutare + " Disk " + nrDiscuri +
" " + tijaSursa + " --> "+ tijaDestinatie);
solutiaHanoi(nrDiscuri-1,tijaIntermediara,tijaSursa,tijaDestinatie);
}
}// solutiaHanoi
}// class
Probleme
1. Realizati un program care citeste dintr-un fisier elementele unui vector, si le ordoneaza folosind
QuickSort. Rezultatul va fi salvat intr-un fisier.
2. Realizati un program care citeste dintr-un fisier elementele unui vector, si le ordoneaza folosind
MergeSort. Rezultatul va fi salvat intr-un fisier
4. Se considera un sir de numere naturale x1, x2, ..., xn si o succesiune de decizii d1, d2, ... unde di
∈{S,D} au urmatoarea semnificatie: la pasul i, sirul ramas ın acel moment se ımparte in doua
subsiruri cu numar egal elemente (daca numarul de elemente este impar, elementul situat la mijloc
se elimina) si se elimina jumatatea din partea stanga a sirului daca di = S (daca di = D se elimina
jumatatea din partea drepta). Deciziile se aplica ın ordine, una dupa alta, pana cand ramane un
singur element. Se cere acest element.
Sirul va fi initializat cu numere aleatoare, iar o posibila succesiune de decizii este d={’S’,’D’,’S’,’S’}