Introducere
Aadar, putem spune c elementele irului se modific n timp real i interogrile se refer la starea curent a irului (cea din momentul cererii de informaii). Enunul problemei n cele ce urmeaz vom prezenta un enun al problemei, particularizat pentru cazul n care interogrile se refer la suma elementelor subsecvenelor. Se consider un ir de numere ntregi care are toate elementele nule. O modificare a unui element const n adunarea unei valori la valoarea curent (pot fi realizate i scderi care au forma adunrii unor valori negative). Pe parcursul modificrilor pot aprea interogri referitoare la suma elementelor unei subsecvene a irului. Problema poate fi enunat n multe alte forme. Una dintre ele ar putea fi urmtoarea: Un furnizor lucreaz cu N distribuitori; n fiecare moment distribuitorii pot efectua pli sau pot cumpra produse. De asemenea, n fiecare moment furnizorul poate cere informaii referitoare la suma total a datoriilor pe care le au magazinele cu numere de ordine cuprinse ntre dou valori date. Evident, exist multe alte enunuri echivalente. De asemenea, pot aprea enunuri n care operaia de nsumare ar putea fi nlocuit cu altele. De exemplu, furnizorul ar putea dori s cunoasc datoria maxim a unui magazin care are numrul de ordine cuprins ntre dou valori date. Exemplu Vom exemplifica acum evoluia n timp real a unui ir format din cinci elemente, prezentnd valorile irului dup fiecare modificare i rezultatul fiecrei interogri. Operaia Iniializare const n setarea la 0 a valorilor tuturor elementelor. Operaia Adun(i, x) const n adunarea valorii x la valoarea curent a celui de-al i-lea element.
16
Operaia Sum(a, b) furnizeaz suma elementelor subsecvenei <a, b>. Operaie Iniializare Adun(1, 3) Adun(4, 5) Sum(3, 3) Sum(4, 4) Adun(4, 2) Adun(2, 3) Sum(2, 5) Sum(2, 4) Adun(5, 2) Sum(2, 4) Sum(2, 5) Adun(3, 1) Adun(4, -2) Sum(2, 5) Adun(1, -3) Adun(5, 5) Sum(1, 2) Sum(3, 4) Adun(2, -1) Adun(3, 3) Sum(5, 5) Sum(1, 2) Sum(1, 5) ir/Rezultat
0 0 3 0 3 0 0 5 3 0 3 3 10 10 3 3 10 12 3 3 3 3 11 0 3 0 3 3 6 0 2 0 2 7 2 18 0 0 0 0 0 0 0 5 0
citete cod ct timp cod 3 execut dac cod = 1 //modificare atunci scrie Introducei indicele elementului care va fi
modificat:
focus
0 7 0 0 7 0
0 7 2
1 7 2 1 5 2 1 5 2 1 5 7
citete val aind aind + val altfel //interogare scrie Introducei extremitile subsecvenei: citete st, dr suma 0 pentru i st, dr execut suma suma + ai sfrit pentru scrie Suma elementelor secvenei este, suma sfrit dac scrie Introducei codul operaiei: citete cod sfrit ct timp
1 5 7 4 5 7
Cazul unidimensional
Din modul n care a fost enunat problema, rezult c operaiile sunt efectuate asupra unui tablou unidimensional; aadar, acesta este cazul unidimensional al problemei. Vom prezenta n continuare trei algoritmi care pot fi folosii pentru rezolvarea problemei i apoi le vom studia performanele. Algoritmul naiv Cea mai intuitiv metod de rezolvare const n pstrarea unui vector cu valorile irului, modificarea lor atunci cnd este necesar i calcularea sumelor n momentul n care apar interogri. Pentru a prezenta algoritmul vom considera c o modificare este codificat prin valoarea 1, iar o interogare prin valoarea 2. Ar fi necesar o a treia operaie (codificat prin 3) care ar indica faptul c nu mai exist modificri sau interogri, deci execuia poate fi ncheiat. Versiunea n pseudocod este prezentat n continuare:
//iniializri scrie Introducei numrul de elemente: citete N //dimensiunea irului pentru i 1, N execut ai 0 //valorile iniiale sunt nule sfrit pentru scrie Introducei codul operaiei:
Se observ c modificrile se efectueaz n timp constant deoarece implic doar accesarea unui element al vectorului i modificarea valorii sale. Datorit faptului c pentru calcularea sumei elementelor unei subsecvene este necesar parcurgerea tuturor elementelor subsecvenei, aceast operaie are ordinul de complexitate O(l), unde l este lungimea subsecvenei. Trebuie observat faptul c algoritmul este acelai dac operaia de nsumare este nlocuit cu o alta (calcularea produsului, stabilirea minimului etc.). Vector de sume Prima ncercare de optimizare const n gsirea unui algoritm mai rapid pentru calcularea sumei elementelor unei subsecvene. O posibilitate relativ simpl este pstrarea unui vector b a crui elemente bi reprezint suma primelor elemente ale irului a. Pentru a gsi suma elementelor unei subsecvene <st, dr> vom efectua o simpl diferen: bdr bst-1. Pentru a calcula sumele pentru subsecvene de forma <1, dr> vom avea nevoie de elementul b0 care va avea ntotdeauna valoarea 0. Astfel, pentru o subsecven de aceast form suma elementelor va fi bdr - b0 = bdr. Aadar, folosind acest artificiu, ordinul de complexitate al unei interogri va fi O(1) pentru c este necesar doar o simpl scdere pentru furnizarea rezultatului. Din nefericire, n momentul efecturii unei modificri pentru elementul i, toate elementele bj pentru care j i i modific valoarea. Ca urmare, operaia de modificare a celui de-al i-lea element nu se mai realizeaz n timp constant, deoarece trebuie modificate N - i + 1 valori. Aadar, ordinul de complexitate devine liniar.
17
Astfel, am reuit s nlocuim algoritmul liniar de determinare a sumei elementelor unei subsecvene cu un algoritm avnd ordinul de complexitate O(1) cu preul creterii timpului de execuie a algoritmului de modificare de la unul constant la unul liniar. Se observ c nu mai avem nevoie de irul a folosit pentru algoritmul anterior, fiind suficient pstrarea valorilor elementelor irului b. Prezentm versiunea n pseudocod a acestui algoritm, folosind aceleai coduri pentru operaiile efectuate:
//iniializri scrie Introducei numrul de elemente: citete N //dimensiunea irului pentru i 0, N execut bi 0 //valorile iniiale sunt nule sfrit pentru scrie Introducei codul operaiei: citete cod ct timp cod 3 execut dac cod = 1 //modificare atunci scrie Introducei indicele elementului care va fi
modificat:
citete val pentru i ind, N execut bi bi + val sfrit pentru altfel //interogare scrie Introducei extremitile subsecvenei: citete st, dr scrie Suma elementelor secvenei este bdr - bst-1 sfrit dac scrie Introducei codul operaiei: citete cod sfrit ct timp
vectorul de sume este mai performant. Totui, n cazul mediu, ambii algoritmi sunt liniari. n cele ce urmeaz vom prezenta o structur de date care permite efectuarea n timp logaritmic att a modificrilor, ct i a interogrilor. Structura de date pe care o propunem este numit arbore indexat binar. Aadar, vom avea o structur arborescent care va permite efectuarea interogrilor n timp logaritmic n condiiile n care i modificrile se efectueaz n timp logaritmic. Pentru a folosi aceast structur de date, va trebui s considerm c elementele irului sunt numerotate ncepnd cu 1. Arborele va fi pstrat sub forma unui vector c n care fiecare element i va conine suma elementelor subsecvenei <i - 2k + 1, i>, unde k este numrul zerourilor terminale din reprezentarea binar a lui i. Aadar, elementele de pe poziiile impare ale arborelui vor pstra suma elementelor unor subsecvene formate dintr-un singur element (aflat pe o poziie impar n irul a). n elementele de pe poziiile de forma 4 k + 2 (un zero terminal n reprezentarea binar a poziiei) vom pstra suma elementelor unor subsecvene formate din dou elemente. n elementele de pe poziiile de forma 8 k + 4 (dou zerouri terminale n reprezentarea binar a poziiei) vom pstra suma elementelor unor subsecvene formate din patru elemente. n general, dac reprezentarea binar a poziiilor au p zerouri terminale, atunci elementele din arbore vor pstra sume ale elementelor unor subsecvene cu 2p elemente. Vom considera c, la un moment dat, irul (format din 15 elemente) este (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15). Valorile vectorului c (cel care reprezint arborele indexat binar) sunt: Element c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 Poziie
0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
focus
Din nou, algoritmul este acelai dac operaia de nsumare este nlocuit cu o alta (calcularea produsului, stabilirea minimului etc.). Arbore indexat binar Practic, pentru algoritmii anteriori una dintre cele dou operaii se efectueaz n timp constant, n timp ce cealalt se efectueaz n timp liniar. Aadar, dac numrul de modificri este aproximativ egal cu cel al interogrilor, timpul de execuie va fi aproximativ acelai. Dac numrul modificrilor este mult mai mare dect cel al interogrilor, atunci este preferabil folosirea algoritmului naiv. Dac, dimpotriv, numrul interogrilor este mult mai mare dect cel al modificrilor, atunci algoritmul bazat pe
Semnificaie Sum(1, 1) Sum(1, 2) Sum(3, 3) Sum(1, 4) Sum(5, 5) Sum(5, 6) Sum(7, 7) Sum(1, 8) Sum(9, 9) Sum(9, 10) Sum(11, 11) Sum(9, 12) Sum(13, 13) Sum(13, 14) Sum(15, 15)
Valoare
1 3 3 10 5 11
36 9 19 11 42 13 27 15
18
Vom prezenta n continuare modul n care se efectueaz modificrile, exemplificnd pe arborele prezentat anterior. n acest scop, vom modifica valoarea celui de-al doilea element din 2 n 8 (se adun valoarea 6).
Se observ c trebuie modificate toate valorile vectorului c care reprezint sume ale unei subsecvene care conine al doilea element al irului; acestea sunt: c2, c4 i c8. Reprezentrile binare ale acestor trei poziii sunt 0010, 0100 i 1000. Se observ c, fiecare astfel de reprezentare (evident, cu excepia primeia) poate fi obinut din cea anterioar prin adunarea valorii 2r, unde r reprezint numrul de zerouri terminale ale reprezentrii binare a poziiei anterioare. Aadar, ar trebui s efectum astfel de adunri pn n momentul n care poziia obinut este mai mare dect dimensiunea irului i s cretem cu 6 valorile tuturor elementelor de pe poziiile de la fiecare pas. Vom exemplifica procedeul i pentru al treilea element. Prima poziie este 0011; numrul zerourilor terminale este 0, deci vom aduna valoarea 20 = 1. Noua poziie va fi 3 + 1 = 4, deci am ajuns la poziia 4 a crei reprezentare binar este 0100. Numrul zerourilor terminale este 2, deci vom aduna valoarea 22 = 4, poziia devenind 4 + 4 = 8. Reprezentarea binar este 1000, deci avem trei zerouri terminale. Valoarea adunat va fi 23 = 8, deci ajungem n poziia 8 + 8 = 16, aadar am depit dimensiunea irului. Se observ c elementele c3, c4 i c8 sunt cele a cror valoare depinde de valoarea elementului de pe a treia poziie. Algoritmul care realizeaz operaia de modificare este urmtorul: Se identific poziia elementului care trebuie modificat. Ct timp poziia curent este cel mult egal cu dimensiunea irului: Se modific valoarea elementului de pe poziia curent. Se determin numrul k al zerourilor terminale din reprezentarea binar a poziiei curente. Noua poziie se determin adunnd valoarea 2k la poziia curent. Se observ c numrul elementelor modificate este cel mult egal cu numrul cifrelor reprezentrii binare a numrului de elemente din ir, deci operaia are ordinul de complexitate O(log N). Mai trebuie prezentat modul n care este efectuat operaia de interogare. Vom ncerca s aplicm o metod similar celei propuse n cazul algoritmului care folosete un vector de sume. Pentru aceasta, dac dorim s determinm suma elementelor subsecvenei <st, dr>, vom determina sumele elementelor subsecvenelor <1, st - 1> i <1, dr>, efectund apoi o simpl diferen. Operaiile efectuate sunt, oarecum, inversele celor de la operaia de modificare. Vom porni din poziia dat i, la fiecare pas, vom determina urmtoarea poziie scznd valoarea 2k unde k reprezint numrul zerourilor terminale din reprezentarea binar a poziiei curente. Ne vom opri n momentul n care poziia curent devine 0. De exemplu, pentru a determina suma elementelor subsecvenei <1, 11> vom porni din poziia 11 a crei reprezentare binar este 1011. Numrul zerourilor terminale
este 0, deci vom scdea valoarea 20 = 1, ajungnd n poziia 11 - 1 = 10. Reprezentarea binar a acesteia este 1010, deci numrul zerourilor terminale este 1. Valoarea sczut este 21 = 2, deci se ajunge n poziia 10 - 2 = 8, a crei reprezentare binar este 1000. De data aceasta avem trei zerouri terminale, deci vom scdea valoarea 23 = 8 ajungnd n poziia 8 - 8 = 0. Aadar, am "trecut" prin poziiile 11, 10 i 8. Adunnd valorile elementelor corespunztoare (c11, c10 i c8) obinem 11 + 19 + 36 = 66, adic exact valoarea cutat. Este uor de observat c c11 reprezint suma elementelor subsecvenei <11, 11>, c10 reprezint suma elementelor subsecvenei <9, 10>, iar c8 reprezint suma elementelor subsecvenei <1, 8>, aadar, n momentul calculrii sumei, fiecare element de pe o poziie mai mic sau egal cu 11 este adunat o singur dat. Pentru a determina suma elementelor unei subsecvene de forma <1, dr> vom folosi urmtorul algoritm: Se identific elementul de pe poziia dr. Ct timp poziia curent este diferit de 0: Se adun la suma total valoarea elementului de pe poziia curent. Se determin numrul k al zerourilor terminale din reprezentarea binar a poziiei curente. Noua poziie se determin scznd valoarea 2k din poziia curent. Evident, pentru a determina suma elementelor unei subsecvene de forma <st, dr> vom aplica de dou ori algoritmul prezentat: o dat pentru subsecvena <1, dr> i o dat pentru subsecvena <1, st-1>, efectund la final diferena valorilor obinute. De exemplu, pentru determinarea sumei elementelor subsecvenei <4, 13> vom calcula mai nti sumele elementelor subsecvenelor <1, 13> i <1, 3>. Acestea sunt Sum(1, 13) = c13 + c12 + c8 = 13 + 42 + 36 = 91 i Sum(1, 3) = c3 + c2 = 3 + 3 = 6, diferena lor fiind 91 - 6 = 85 care este egal cu valoarea Sum(4, 13). Se observ c numrul elementelor adunate este cel mult egal cu numrul cifrelor reprezentrii binare a poziiei elementului dat, deci operaia are ordinul de complexitate O(log N). Din nou, se observ c nu avem nevoie de pstrarea elementelor irului a, fiind suficient pstrarea valorilor vectorului c (cel care reprezint arborele indexat binar). Varianta n pseudocod a algoritmului de rezolvare a problemei folosind un arbore indexat binar este urmtoarea:
//iniializri scrie Introducei numrul de elemente: citete N //dimensiunea irului pentru i 0, N execut ci 0 //valorile iniiale sunt nule sfrit pentru
focus
19
GInfo nr. 13/1 - ianuarie 2003
scrie Introducei codul operaiei: citete cod ct timp cod 3 execut dac cod = 1 //modificare atunci scrie Introducei indicele elementului care va fi
modificat:
focus
st st - 2poz poz poz + 1 sfrit ct timp scrie Suma elementelor subsecvenei este: s1 s2 sfrit dac scrie Introducei codul operaiei: citete cod sfrit ct timp
20
citete val poz 0 //poziia celui mai nesemnficativ bit cu //valoarea 1 ct timp ind N execut cind cind + val ct timp ind & 2poz 0 execut //& reprezint operaia de conjucie //logic (I-logic) poz poz + 1 sfrit ct timp ind ind + 2poz poz poz + 1 //valoarea poz este incrementat //i nu reiniializat cu 0 deoarece //tim c acum avem cel puin //poz + 1 zeroruri terminale, prin //adunare adugndu-se cel puin //un zero terminal sfrit ct timp altfel //interogare scrie Introducei extremitile subsecvenei: citete st, dr //calcularea primei sume s1 0 //iniializare poz 0 //poziia celui mai nesemnficativ bit cu //valoarea 1 ct timp dr > 0 execut s1 s1 + cdr ct timp dr & 2poz = 0 execut poz poz + 1 sfrit ct timp dr dr - 2poz poz poz + 1 //prin scdere se adaug cel //puin un zero terminal sfrit ct timp //calcularea celei de-a doua sume st st - 1 //trebuie calculat valoarea pentru //st-1 s2 0 //iniializare poz 0 //poziia celui mai nesemnficativ bit cu //valoarea 1 ct timp st > 0 execut s2 s2 + cst ct timp st & 2poz = 0 execut poz poz + 1 sfrit ct timp
i de data aceasta putem nlocui operaia de nsumare cu alte operaii (nmulire, minim, maxim etc.).
Cazul bidimensional
Problema enunat poate fi modificat astfel nct s lucrm n spaiul bidimensional. Enunul noii probleme ar putea fi urmtorul: Se consider o matrice de numere ntregi care are toate elementele nule. O modificare a unui element al matricei const n adunarea unei valori la valoarea curent (pot fi realizate i scderi care au forma adunrii unor valori negative). Pe parcursul modificrilor pot aprea interogri referitoare la suma elementelor unei submatrice. Aadar, n acest caz, interogrile se refer la suma valorilor dintr-o "zon dreptunghiular" care face parte din matrice. Evident, pentru reprezentarea datelor vom folosi tablouri bidimensionale n locul celor unidimensionale (matrice n locul vectorilor). Din nou, enunul poate fi reformulat n diferite moduri. O variant ar putea fi: Se consider un teren de form dreptunghiular avnd lungimea M i limea N. Terenul este mprit n regiuni de form ptrat avnd latura egal cu unitatea. n fiecare moment, ntr-o anumit regiune pot fi plantai sau tiai pomi. De asemenea, n fiecare moment proprietarul terenului ar putea cere informaii referitoare la numrul total al pomilor care se afl ntr-o regiune dreptunghiular a terenului. Vom adapta cei trei algoritmi descrii pentru cazul unidimensional pentru a rezolva noua problem i vom studia apoi performanele acestora. De data aceasta, pentru operaia de modificare vom avea nevoie de doi parametri care vor reprezenta linia i coloana pe care se afl elementul a crui valoare va fi modificat. Pentru interogri vom avea nevoie de patru parametri care vor reprezenta coordonatele colurilor din stnga-sus i dreapta-jos ale unui dreptunghi. Vom exemplifica acum cazul bidimensional al problemei folosind o matrice cu trei linii i trei coloane.
Operaie Iniializare Adun(2, 2, 3) Adun(1, 3, 5) Sum(2, 1, 3, 3) Adun(2, 1, 1) Sum(1, 2, 2, 3) Adun(2, 2, -1) Sum(1, 2, 2, 3) Adun(2, 2, 5) Adun(2, 2, -5) Adun(3, 2, 4) Sum(1, 1, 3, 3)
Matrice/Rezultat
0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 3 0 0 3 0 0 1 3 0 0 8 0 0 1 2 0 0 7 0 0 1 7 0 0 0 0 1 2 0 0 0 0 1 2 0 4 12 0 0 0 0 0 0 5 0 0 5 0 0 5 0 0 5 0 0 5 0 0 5 0 0
citete val aindx,indy aindx,indy + val altfel //interogare scrie Introducei coordonatele colurilor: citete st, sus, dr, jos suma 0 pentru i sus, jos execut pentru j st, dr execut suma suma + aij sfrit pentru sfrit pentru scrie Suma elementelor dreptunghiului este: suma sfrit dac scrie Introducei codul operaiei citete cod sfrit ct timp
focus
Modificrile se efectueaz tot n timp constant deoarece implic doar accesarea unui element al matricei i modificarea valorii sale. Datorit faptului c pentru calcularea sumei elementelor dintr-un dreptunghi este necesar parcurgerea tuturor elementelor dreptunghiului, aceast operaie are ordinul de complexitate O(l h), unde l i h sunt lungimile laturilor dreptunghiului. Matrice de sume Adaptarea algoritmului care folosete un vector de sume este destul de simpl. Vom pstra o matrice b ale creia elemente bij vor conine sumele corespunztoare dreptunghiurilor cu colul din stnga-sus n poziia (1, 1) i cel din dreapta-jos n poziia (i, j). Studiind figura alturat, este uor de observat c pentru a calcula valoarea Sum(st, sus, dr, jos) poate fi folosit relaia: Sum(st, sus, dr, jos) = Sum(1, 1, dr, jos) Sum(1, 1, st - 1, jos) Sum(1, 1, dr, sus - 1) + Sum(1, 1, st - 1, sus - 1). Se observ c prin scderea valorii Sum(1, 1, st-1, jos) se scad valorile tuturor elementelor aflate la dreapta dreptunghiului considerat, iar prin scderea valorii Sum(1, 1, dr, sus-1) se scad valorile elementelor aflate deasupra dreptunghiului. Aceste operaii implic scderea de dou ori a tuturor elementelor aflate la stnga i deasupra dreptunghiului considerat, motiv pentru care va trebui s adunm valoarea Sum(1, 1, st-1, sus-1). Folosind acest artificiu avem nevoie de accesarea a patru elemente ale matricei b, deci operaia se realizeaz n timp constant.
Algoritmul naiv Primul algoritm descris pentru cazul unidimensional poate fi adaptat foarte uor pentru a rezolva cazul bidimensional al problemei. Vom pstra valorile matricei, le vom modifica dac este necesar i vom calcula sumele cerute de interogri. Versiunea n pseudocod este prezentat n continuare:
//iniializri scrie Introducei dimensiunile matricei: citete M, N pentru i 1, M execut pentru j 1, N execut aij 0 //valorile iniiale sunt nule sfrit pentru sfrit pentru scrie Introducei codul operaiei: citete cod ct timp cod 3 execut dac cod = 1 //modificare atunci scrie Introducei indicii elementului care va fi
modificat:
21
focus
Din nou, n momentul modificrii valorii unui element de coordonate (x, y), va trebui s modificm valorile tuturor elementelor matricei b de coordonate (i, j) pentru care i x i j y. Aadar, vom modifica (M - x + 1) (N - y + 1) elemente, ordinul de complexitate devenind O(M N). Pentru a putea determina valori pentru dreptghiuri n care colul din stnga-sus are una dintre coordonate egal cu 1 va trebui s considerm c valorile elementelor matricei sunt nule dac cel puin unul dintre cei doi indici este 0. Prezentm versiunea n pseudocod a algoritmului descris:
//iniializri scrie Introducei dimensiunile matricei: citete M, N //dimensiunea irului pentru i = 0, M execut pentru i = 0, N execut bij = 0 //valorile iniiale sunt nule sfrit pentru sfrit pentru scrie Introducei codul operaiei: citete cod ct timp cod 3 execut dac cod = 1 //modificare atunci scrie Introducei indicii elementului care va
Pentru a rezolva problema vom crea un arbore de arbori indexai binar. Aadar, vom avea o matrice c ale crei elemente cij vor reprezenta sumele elementelor din dreptunghiul care are colul din stnga-sus n poziia (i - 2k + 1, j - 2l + 1), iar cel din dreapta-jos n poziia (i, j). Valoarea k reprezint numrul zerourilor terminale din reprezentarea binar a lui i, iar l reprezint numrul zerourilor terminale din reprezentarea binar a lui j. De exemplu, pentru matricea:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
fi modificat:
citete val pentru i indx, M execut pentru i indy, N execut bij bij + val sfrit pentru sfrit pentru altfel //interogare scrie Introducei coordonatele colurilor: citete st, sus, dr, jos scrie Suma elementelor secvenei este: bdr,jos bst-1,jos - bdr,sus-1 + bst-1,sus-1. sfrit dac scrie Introducei codul operaiei citete cod sfrit ct timp
Din nou, algoritmul este foare asemntor dac operaia de nsumare este nlocuit cu o alta (calcularea produsului, stabilirea minimului etc.). Arbore de arbori indexai binar Din nou, avem doi algoritmi n care una dintre operaii este eficient, n timp ce cealalt necesit un timp de execuie mai mare. Folosind arborii indexai binar, vom putea gsi algoritmi care realizeaz ambele operaii ntr-un timp de ordinul O(log M log N), unde M i N sunt dimensiunile matricei.
22
S presupunem c trebuie s modificm valoarea elementului de coordonate (2, 1) care face parte dintr-o matrice cu 8 linii i 4 coloane. Vom aplica de dou ori principiul descris pentru cazul unidimensional. Vom identifica linia i pe care se afl elementul i vom efectua modificri n toate coloanele de pe acea linie n care acestea trebuie efectuate. Pentru aceasta vom identifica coloana j, vom determina numrul k al zerourilor terminale i apoi vom aduna la j valoarea 2k. Ajungem ntr-o nou poziie i continum procedeul pn n momentul n care valoarea coloanei curente depete numrul de coloane al matricei. n acest moment vom determina numrul zerourilor terminale l din reprezentarea binar a valorii i i ne vom "muta" pe linia i + 2l. Vom reveni la coloana j i vom parcurge aceeai pai ca i la linia anterioar. Vom continua pn n momentul n care valoarea liniei curente va fi mai mare dect numrul de linii ale matricei. Pe fiecare linie vom modifica cel mult log2N elemente; n plus, vom modifica elemente de pe cel mult log2M linii, aadar, ordinul de complexitate al operaiei de modificare a unui element este O(log M log N). Ca urmare, dac se modific elementul de coordonate (3, 1), atunci vor trebui modificate urmtoarele elemente
ale matricei care reprezint arborele de arbori indexai binar: c31, c32, c34, c41, c42, c44, c81, c82 i c84. n cazul n care dorim s efectum o interogare vom folosi aceeai metod. Singura diferen este, din nou, faptul c valorile de forma 2k sunt sczute n loc s fie adunate. Datorit faptului c, de data aceasta, avem nevoie de patru sume pentru a furniza rezultatul, algoritmul va fi aplicat de patru ori. Ordinul de complexitate al algoritmului va fi O(log M log N). Vom prezenta n continuare versiunea n pseudocod a algoritmului de rezolvare a problemei n cazul bidimensional, folosind un arbore de arbori indexai binar.
scrie Introducei dimensiunile matricei: citete M, N pentru i 0, M execut pentru j 0, N execut cij 0 //valorile iniiale sunt nule sfrit pentru sfrit pentru scrie Introducei codul operaiei citete cod ct timp cod 3 execut dac cod = 1 //modificare atunci scrie Introducei indicii elementului care va fi
//iniializri
modificat:
citete val pozi 0 ct timp indx M execut pozj 0 j indy ct timp j N execut cindx,j cindx,j + val ct timp indx & 2pozj = 0 execut pozj pozj + 1 sfrit ct timp j j + 2pozj pozj pozj + 1 sfrit ct timp ct timp indx & 2pozi = 0 execut pozi pozi + 1 sfrit ct timp indx indx + 2pozi pozi pozi + 1 sfrit ct timp altfel //interogare scrie Introducei coordonatele colurilor: citete st, sus, dr, jos //calcularea primei sume s0 x jos
y dr pozi 0 ct timp x 0 execut pozj 0 jy ct timp y 0 execut s1 s1 + cx,j ct timp x & 2pozj = 0 execut pozj pozj + 1 sfrit ct timp j j - 2pozj pozj pozj + 1 sfrit ct timp ct timp x & 2pozi = 0 execut pozi pozi + 1 sfrit ct timp x x - 2pozi pozi pozi + 1 sfrit ct timp s1 s s0 //calcularea celei de-a doua sume x jos y st - 1 ... //se aplic exact aceeai secven s2 s s0 //calcularea celei de-a treia sume x sus - 1 y dr ... //se aplic din nou exact aceeai secven s3 s s0 //calcularea celei de-a patra sume x sus - 1 y dr - 1 ... //se aplic din nou exact aceeai secven s4 s scrie Suma elementelor dreptunghiului este s1 - s2 - s3 + s4 sfrit dac scrie Introducei codul operaiei: citete cod sfrit ct timp
focus
GInfo nr. 13/1 - ianuarie 2003
Cazul tridimensional
Problema enunat poate fi modificat astfel nct s lucrm n spaiul tridimensional. Enunul ar putea fi urmtorul: Se consider un tablou tridimensional care conine numere ntregi i toate elementele sale sunt nule. O modificare a unui element al tabloului const n adunarea unei valori la valoarea curent (pot fi realizate i scderi care au forma adunrii unor valori negative). Pe parcursul modificrilor pot aprea interogri referitoare la suma elementelor unui subtablou "paralelipipedic" .
23
Aadar, n acest caz, interogrile se refer la suma valorilor dintr-o "zon paralelipipedic" a tabloului. Evident, pentru reprezentarea datelor vom folosi tablouri tridimensionale. i acest enun poate fi reformulat n diferite moduri. O variant ar putea fi: O zon a spaiului este reprezentat de un paralelipiped format din cuburi cu latura egal cu unitatea. Dimensiunile paralelipipedului sunt M, N i P. n fiecare sector (cub) pot sosi sau pleca nave spaiale. De asemenea, n fiecare moment amiralul flotei poate cere informaii referitoare la numrul total de nave spaiale dintr-o regiune paralelipipedic din aceast zon a spaiului. Nu vom mai prezenta pe larg cele trei tipuri de algoritmi; vom face doar cteva precizri care ne vor ajuta s generalizm problema pentru spaii n-dimensionale. n primul rnd, n fiecare poziie n care algoritmii pentru cazul bidimensional conineau dou cicluri imbricate, pentru algoritmii care rezolv cazul tridimensional vom avea trei cicluri. Ca urmare, ordinul de complexitate al primilor doi algoritmi va deveni O(M N P). Ordinul de complexitate al celui de-al treilea algoritm va fi O(log M log N log P). n al doilea rnd, elementele tabloului tridimensional vor fi identificate prin trei indici. Aadar, pentru o modificare vom avea nevoie de trei parametri "geometrici", iar pentru o interogare de ase astfel de parametri. n al treilea rnd, pentru ultimii doi algoritmi va trebui s calculm opt sume n loc de patru. Formula de calcul va fi urmtoarea: Sum(x1, y1, z1, x2, y2, z2) = Sum(1, 1, 1, x2, y2, z2) Sum(1, 1, 1, x1 - 1, y2, z2) Sum(1, 1, 1, x2, y1 - 1, z2) Sum(1, 1, 1, x2, y2, z1 - 1) + Sum(1, 1, 1, x1 - 1, y1 - 1, z2) + Sum(1, 1, 1, x1 - 1, y2, z1 - 1) + Sum(1, 1, 1, x2, y1 - 1, z1 - 1) Sum(1, 1, 1, x1 - 1, y1 - 1, z1 - 1) Mai precizm faptul c pentru cel de-al treilea algoritm vom folosi un tablou tridimensional care va reprezenta un arbore de arbori de arbori indexai binar. Toate celelalte aspecte ale celor trei algoritmi descrii pot fi adaptate foarte simplu pentru a rezolva problema tridimensional.
la valoarea curent (pot fi realizate i scderi care au forma adunrii unor valori negative). Pe parcursul modificrilor pot aprea interogri referitoare la suma elementelor unui subtablou. Aadar, n acest caz, interogrile se refer la suma valorilor dintr-o "zon n-dimensional" a tabloului. Evident, pentru reprezentarea datelor vom folosi tablouri n-dimensionale. De data aceast, cele dou cicluri imbricate din algoritmii pentru cazul bidimensional (cele trei din algoritmii pentru cazul tridimensional) vor fi nlocuite de n cicluri imbricate. Ca urmare, ordinul de complexitate al primilor doi algoritmi va depinde de produsul celor n dimensiuni, iar ordinul de complexitate al celui de-al treilea algoritm va depinde de produsul logaritmilor celor n dimensiuni. Evident, vom avea acum n parametri "geometrici" pentru o modificare i 2 n parametri de acest tip pentru o interogare. Numrul sumelor care trebuie calculate pentru o interogare (la al doilea i al treilea algoritm) este, pentru cazul general, 2n. innd cont de aceste observaii, algoritmii prezentai pot fi folosii pentru rezolvarea unor probleme de acest tip n care numrul dimensiunilor este orict de mare.
focus
Concluzii
n cadrul acestui articol am prezentat o structur de date care permite rezolvarea eficient a unei categorii de probleme. Pentru a evidenia performanele algoritmilor care folosesc o astfel de structur de date, am prezentat i alte dou categorii de algoritmi, mult mai uor de implementat, dar ineficieni. De asemenea, am prezentat modul n care pot fi generalizai algoritmii folosii pentru cazul cel mai simplu (cel unidimensional) pentru a rezolva problema pentru cazuri n care numrul dimensiunilor este orict de mare. Am exemplificat algoritmii pentru cazul n care interogrile se refer la suma anumitor elemente. Cu toate acestea este evident faptul c, n cazul tuturor acestor algoritmi, aceast operaie poate fi nlocuit cu altele (produsul elementelor, minimul sau maximul lor etc.). 1. J. Nummenmaa, E. Mkinen, I. Aho, IOI '01 Competition, Tampere, Finland, 2001 2. P. M. Fenwick, A new data structure for cumulative frequency tables, Software-Practice and Experience, vol. 24, no. 3, p. 327-336, 1994 3. T. H. Cormen, C. E. Leiserson, R. R. Rivest, Introducere n algoritmi, Computer Libris Agora, Cluj-Napoca, 2000
Bibliografie
Cazul n-dimensional
Vom generaliza acum problema pentru a putea fi enunat ntr-un spaiu cu un numr orict de mare de dimensiuni. O variant a enunului este: Se consider un tablou n-dimensional care conine numere ntregi i toate elementele sale sunt nule. O modificare a unui element al tabloului const n adunarea unei valori
24
Mihai Scoraru este redactor-ef al GInfo. Poate fi contactat prin e-mail la adresa skortzy@yahoo.com.