Documente Academic
Documente Profesional
Documente Cultură
RAPORT
despre lucrarea de laborator nr. 6
Varianta 18
5. în raport de descris concis esenţa fiecărei metode ( ca strategie sau tehnică de programare).
Algoritmi:
- Greedy: (greedy = lacom) sunt în general simpli şi sunt folosiţi în probleme de optimizare în care se poate
obţine optimul global în alegeri succesive ale optimului local, ceea ce permite rezolvarea problemei fãrã nici
o revenire la deciziile anterioare. În acest sens avem:
o mulţime de candidaţi (lucrari de executat, varfuri ale grafului etc)
o funcţie care verificã dacã o anumitã mulţime de candidaţi constituie o soluţie posibilã, nu neapãrat
optimã, a problemei
o funcţie care verificã dacã o mulţime de candidaţi este fezabilã, adicã dacã este posibil sã completãm
aceastã mulţime astfel încât sã obţinem o soluţie posibilã, nu neapãrat optimã, a problemei
o funcţie de selecţie care indicã la orice moment care este cel mai promiţãtor dintre candidaţii încã
nefolosiţi
o funcţie obiectiv care dã valoarea unei soluţii; aceasta este funcţia pe care dorim sã o optimizãm
(minim/maxim).
- Branch and Bound: foloseste la rezolvarea problemelor la care domeniul în care se caută soluţia este foarte
mare şi nu se cunoaşte un alt algoritm care să conducă mai rapid la rezultat. Problemele care pot fi abordate
prin această metodă pot fi modelate într-un mod asemănător celui folosit la metoda Backtracking. Se pleacă
de la o configuraţie iniţială şi se reţine şirul de operaţii prin care aceasta este transformată într-o configuraţie
finală dacă aceasta este dată, în alte cazuri se cere configuraţia finală ştiind că trebuie să verifice anumite
condiţii de optim.
REZOLVARE
PROBLEMA 24.
Reţeaua binară: Se dau numerele naturale m şi n. Se consideră o reţea dreptunghiulară având 2m linii şi 2n coloane. Se
cere să se atribuie nodurilor reţelei numere naturale distincte din mulţimea {0,1,...,2m+n-1}, astfel încât pentru orice
două vârfuri vecine (pe orizontală sau pe verticală) reprezentarea lor binară să difere pe o unică poziţie.
R. Folosim metoda backtracking generând cele 2m+n numere, verificând condiţiile ca numărul din poziţia R(k-1) şi R(k-
2n) pentru k corespunzător să difere pe o unică poziţie faţă de R(k), R(k) {0,1,...,2m+n-1}, k=1,2m+n.
int rows,cols,nums;
int **network;
//Verifică dacă 2 numere se deosebesc doar printr-un bit
bool compareBinary(int a,int b){
int x=a^b;
int count = 0;
while(x){
x&=(x-1);
count++;
if(count>1) return false;
}
if(count==1) return true;
}
//Afisarea retelei binare
void displayNetwork(int **network){
printf("Reteaua binara este:\n");
int i,j;
for(i=0;i<rows;i++){
for(j=0;j<cols;j++){
printf("%d\t",network[i][j]);
}
putchar('\n');
}
}
//Verificare dacă numărul introdus nu se repetă, și dacă pe orizontală sau
//verticală are vecini ce se deosebesc printr-un bit doar
bool check(int **network,int i,int j){
int x,y,k,m;
for(x=0;x<rows;x++){
for(y=0;y<cols;y++){
for(m=0;m<rows;m++){
for(k=0;k<cols;k++){
if(x!=m || y!=k)
if(network[x][y]!=-1 &&
network[x][y]==network[m][k]){
return false;
}
}
}
}
}
//check top
if(i!=0 && network[i-1][j]!=-1)
if(compareBinary(network[i][j],network[i-1][j])==false)
return false;
//check right
if(j<cols-1 && network[i][j+1]!=-1)
if(compareBinary(network[i][j],network[i][j+1])==false)
return false;
//check down
if(i<rows-1 && network[i+1][j]!=-1)
if(compareBinary(network[i][j],network[i+1][j])==false)
return false;
//check left
if(j!=0 && network[i][j-1]!=-1)
if(compareBinary(network[i][j],network[i][j-1])==false)
return false;
return true;
}
//Găsirea numerelor ce respectă condițiile de mai sus și inserarea în rețea
bool findSolution(int **network){
int i,j,k;
for(i=0;i<rows;i++)
for(j=0;j<cols;j++){
if(network[i][j]==-1){
for(k=0;k<=nums;k++){
network[i][j]=k;
if(check(network,i,j)){
if (findSolution(network))
return true;
}
}
}
}
}
int main(int argc, char *argv[]) {
int i,j,m,n;
printf("Introduceti m si n:\n");
scanf("%d %d",&m,&n);
rows=pow(2,m);
cols=pow(2,n);
nums=pow(2,n+m)-1;
network=(int**)malloc(sizeof(int*)*rows);
for(i=0;i<rows;i++){
network[i]=(int*)malloc(sizeof(int)*cols);
for(j=0;j<cols;j++){
network[i][j]=-1;
}
}
if(findSolution(network))
displayNetwork(network);
return 0;
}
Rezultat:
PROBLEMA 32.
Mergesort(sortarea prin interclasare, Divide et Impera): Fie T[1 .. n] un tablou pe care dorim sa-l sortam crescator.
Prin tehnica divide et impera putem proceda astfel: separam tabloul T in doua parti de marimi cat mai apropiate,
sortam aceste parti prin apeluri recursive, apoi interclasam solutiile pentru fiecare parte, fiind atenti sa pastram
ordonarea crescatoare a elementelor.
int main(){
int n,*arr,i;
srand(time(0));
printf("Introduceti numarul de elemente: ");
scanf("%d",&n);
arr=malloc(n*sizeof(int));
for(i=0;i<n;i++)
arr[i]=rand()%50-rand()%50+1;
printArray(arr,n);
mergeSort(arr,0,n-1);
printf("Array-ul sortat: \n");
printArray(arr,n);
return 0;
}
void merge(int arr[], int l, int m, int r){
int i,j,k;
int n1=m-l+1;
int n2=r-m;
int L[n1],R[n2];
for (i=0;i<n1;i++)
L[i]=arr[l+i];
for (j=0;j<n2;j++)
R[j]=arr[m+1+j];
i=0,j=0,k=l;
while(i<n1 && j<n2){
if (L[i]<=R[j]){
arr[k]=L[i];
i++;
}
else{
arr[k]=R[j];
j++;
}
k++;
}
while (i<n1){
arr[k]=L[i];
i++;k++;
}
while (j<n2){
arr[k]=R[j];
j++;k++;
}
}
void mergeSort(int arr[], int l, int r){
if(l<r){
int m=l+(r-l)/2;
mergeSort(arr,l,m);
mergeSort(arr,m+1,r);
merge(arr, l, m, r);
}
}
Rezultat:
Concluzie:
În urma efectuării lucrării de laborator nr.6, am însușit un lucru extrem de important, tipuri de algoritmi
și utilizarea lor corespunzătoare. Algoritmii sunt foarte puternici în rezolvarea problemelor complicate, în
optimizare, sau găsirea multitudinilor de soluții. Laboratorul dat conține un set de probleme de o
complexitatea mult mai mare decît cele întîlnite pînă acum, iar asta m-a provocat într-o măsură. În sarcinile
oferite am utilizat algoritmul “backtracking” pentru a găsi o rețea binară, ce ar fi destul complicat de
obținut același rezultat fără utilizarea lui, și metoda “Divide et Impera” pentru a sorta un array prin
algoritmul mergesort, adică divizînd array-ul în părți mai mici și sortîndu-le pe fiecare, apoi combinîndu-le
înapoi.