Sunteți pe pagina 1din 6

Inmultirea optima a unui sir de matrice

1. Textul Problemei Se da un numar de n matrice A1, A2, A3, , An, cunoscandu-se dimensiunea fiecarei matrice. Astfel, matricea A1 are dimensiunile (d1, d2), matricea A2, dimensiunile (d2,d3), , Ai(di,di+1). Consideram produsul matricelor A1xA2xA3xxAn. Se cere sa se gaseasca o metoda optima de parantezare a matricelor astfel incat numarul de inmultiri efectuate sa fie minim. Sa se afiseze numarul minim de inmultiri si parantezarea aferenta a matricelor . Obs : Ordinea nu va fi schimbata ; matricele se vor inmulti in ordinea data. Parantezarea se refera la asociativitatea produsului de matrice. 2.1 Explicatii Se cunoaste ca produsul de matrice nu este comutativ, in schimb este asociativ. De exemplu, daca avem de inmultit trei matrice A,B,C produsul se poate face in doua moduri: (AxB)xC sau Ax(BxC). In vederea rezolvarii problemei, retinem o matrice A cu n linii si n coloane. Elementul A(i,j), i<j, reprezinta numarul minim de inmulturi pentru efectuarea produsului AixAi+1xxAj. De asemenea, numarul liniilor si al coloanelor celor n matrice sunt retinute intr-un vector DIM cu n+1 componente. Pentru exemplul nostru DIM retine urmatoarel valori: 10,1,10,1,10. Pentru rezolvare se tine cont de urmatoarele relatii existente intre componentele matricei A: 1) A(i,i)=0; 2) A(i,i+1)=DIM(i)xDIM(i+1)xDIM(i+2); 3) A(i,j)=min{A(i,k)+A(k+1,j)+DIM(i)xDIM(k+1)xDIM(j+1)}. 2.2 Explicatii Justificarea acestor relatii este urmatoare: I. O matrice nu se inmulteste cu ea insasi, deci se efectueaza 0 inmultiri; II. Liniile si coloanele matricei Ai se gasesc in vectorul DIM pe pozitiile i si i+1, iar ale matricei Ai+1, pe pozitiile i+1 si i+2; III. Inmultind matricele AixAi+1xAk, se obtine o matrice cu un numar de linii egal cu acela al matricei Ai (DIM(i)) si cu un numar de coloane egal cu acela al matricei Ak (DIM(k+1)); Inmultind matricele Ak+1xxAj, se obtine o matrice cu un numar de linii egal cu Acela al matricei Ak+1 (DIM(k+1)) si cu un numar de coloane egal cu acela al matricei Aj (DIM(j+1)); Prin inmultirea celor doua matrice se obtine matricea rezultat al inmultirii AixxAj, iar pentru aceasta inmultire de matrice se efectueaza DIM(i)xDIM(k+1)xDIM(j+1) inmultiri.

2.3 Explicatii Relatia sintetizeaza faptul ca pentru a obtine numarul de inmultiri optim pentru produsul AixxAj se inmultesc doua matrice, una obtinuta ca produs optim intre AixxAk si cealalta obtinuta ca produs optim intre Ak+1xAj, in ipoteza in care cunoastem numarul de inmultiri necesar efectuarii acestor doua produse, oricare ar fi k cuprins intre limitele date. Aceasta obervatie este o consecinta directa a programarii dinamice si anume ca produsul efectuat optim intre matricele prezentate se reduce in ultima instanta la a efectua un produs intre doua matrice cu conditia ca acestea sa fie calculate optim (produsul lor sa aiba un numar minim de inmultiri).

3. Exemple numerice Se considera patru matrice : A1(10, 1), A2(1, 10), A3(10, 1), A4(1, 10). Matricea a va evolua astfel :

0 x x x

x 0 x x

x x 0 x

x x x 0

0 1 x x

100 0 2 x

x 10 0 3

x x 100 0

0 1 1 x

100 20 0 2 3 10 0 3

x 20 100 0

0 1 1 1

100 20 120 0 2 3 20 0 3 20 100 0

Parantezarea va evolua astfel: A1 x A2 x A3 x A4 Ne uitam in matricea a pe pozitia a[4][1] = 1. A1 x (A2 x A3 x A4) Ne uitam in matricea a pe pozitia a[4][2]=3 pentru ca in secventa care-l contine pe A1 nu se mai pot face parentazari. A1 x ((A2 x A3) x A4) 4.1 Codul problemei -declarari#include <iostream> using namespace std; int dim[102],n; int des[102],inc[102]; long long a[102][102];

Explicatii: n reprezinta numarul de matrice. dim[102] reprezinta vectorul care retine dimensiunile matricelor. des[102] reprezinta vectorul care retine numarul de paranteze deschise din dreptul fiecarei matrice. inc[102] reprezinta vectorul care retine numarul de paranteze inchise din dreptul fiecarei matrice. a[102][102] reprezinta matricea in care vom opera pentru aflarea numarului minim de inmultiri si pentru aflarea pivotilor necesari functiei parantezeaza 4.2 Codul problemei -citire 1/2void citeste () { bool ok=0; int i; cout<<"Tasteaza numarul de matrice (intreg de la 1 pana la 100)."<<endl; while (!ok) { ok=1; cin>>n; if(n>100||n<1) { ok=0; cout<<"Ai tastat incorect.Tasteaza din nou numarul de matrice (numar intreg cuprins intre 1 si 100)."<<endl; } }

4.3 Codul problemei -citire 2/2ok=0; cout<<"Tastati dimensiunile matricelor (numere intregi cuprinse intre 1 si 100) astfel: "<<endl<<"numarul de linii si numarul de coloane ale primei matrice si apoi doar numarul de coloane al celorlalte matrice."<<endl<<"Prin urmare trebuie indroduse numarul de matrice + numere."; while (!ok) { ok=1; for(i=1;i<=n+1;i++) { cin>>dim[i]; if(dim[i]<1||dim[i]>100) {

ok=0; cout<<"Retasteaza dimensiunile matricelor dupa precizarile de mai sus."; break; }}}}

4.4 Codul problemei -aflarea nr. minim de inmultirivoid inmultireoptima () { int i,j,k,poz; long long min; for (k=1;k<=n-1;k++) { for (i=1;i<=n-k;i++) { j=i+k; a[i][j]=a[i][i]+a[i+1][j]+dim[i]*dim[i+1]*dim[j+1]; a[j][i]=i; for(poz=i+1;poz<j;poz++) { min=a[i][poz]+a[poz+1][j]+dim[i]*dim[poz+1]*dim[j+1]; if (a[i][j]>min) { a[i][j]=min; a[j][i]=poz; }}}}}

4.5 Codul problemei -parantezarea sirului de matricevoid parantezeaza (int p, int u,int des[102],int inc[102]) { if (u-p>1) { int mij=a[u][p]; if(mij!=p) { des[p]++; inc[mij]++; } if(mij+1!=u)

{ des[mij+1]++; inc[u]++; } parantezeaza(p,mij,des,inc); parantezeaza(mij+1,u,des,inc); }} Explicatii: Pentru a paranteza expresia vom numara parantezele deschise si pe cele inchise din dreptul fiecarei matrice. Vom folosi metoda divide et impera. p este indicele primei matrice din secventa de matrice studiata. u este indicele ultimei matrice din secventa studiata. mij reprezinta pivotul dupa care vom sparge secventa studiata.

4.6 Codul problemei -main-ul problemeiint main() { citeste(); inmultireoptima(); cout<<"Cel mai mic numar de inmultiri efectuate pentru a inmulti matricele este"<<a[1][n]<<endl; parantezeaza(1,n,des,inc);cout<<endl; cout<<"Acesta se obtine parantezand astfel: "<<endl; int i,j; for (i=1;i<=n;i++) { for (j=1;j<=des[i];j++) cout<<"("; cout<<"A"<<i; for (j=1;j<=inc[i];j++) cout<<")"; } return 0; }

5. Bibliografia Manual de informatica profil real-intensiv clasa a XI-a - Tudor Sorin & Vlad Hutanu; http://walkinthroughlife.wordpress.com/2010/11/21/programare-dinamica-inmultire-optimamatrici/;

Elevi: Bercoci Iliescu Luca Stefan Darie Teodor Linta Vlad Gabriel Manole Alexandru-Daniel Mitroi Andrei

Clasa a XI-a I