Edit this page Backlinks This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong. ===== Analiza amortizata ===== ==== 1. Stack ==== Naiv: La un momnt dat pot fi k elemente in stack, deci cea mai costisitoare operatie va fi mpop cu complexitate temporala O(k). Daca avem n operatii in secventa (avem deci $ n \leq k $ ), vom avea maxim $ n * O(k) = O(n^2) $ . Dar totusi nu putem face atatea $ mpop(k) $ , pentru ca nu avem elemente. Pentru a putea efectua un $ pop $ , operatia trebuie precedata in secventa $ S $ de un push. Pentru a putea efectua un $ mpop(k) $ , operatia trebuie precedata in secventa $ S $ de $ k $ operatii push. Worst-Case: Cate elemente pot fi adaugate si eliminate **maxim** intr-o secventa de k operatii? * se pot adauga maxim $ (k-1) $ elemente si se pot elimina cu un $ mpop(k-1) $ la final === 1.1. Aggregate method === $ pop $ si $ push $ au cost $ 1 $, $ mpop $ are cost $ k $. $ cost(S) = (k-1) * 1 + (k - 1) = 2k - 2 $ Deci, pentru o singura operatie, avem: $ cost(op) = cost(S) / k = (2k - 2) / k \leq 2 => cost(op) = 2 $ === 1.2. Banking method === Pentru fiecare operatie push, trebuie sa avem in vedere un viitor $ pop $ . Operatiile $ push $ vor creste creditul, iar operatiile $ pop $ si $ mpop $ il vor scadea. Alegem: \\ $ \hat c_{push} = 2 $ \\ $ \hat c_{pop} = 0 $ \\ $ \hat c_{mpop} = 0 $ Aratam ca: $ cost(S) \leq \sum_{i=1}^{n}\hat{c_i} $ . \\ $ cost(S) = 2k - 2 $ (am vazut anterior) \\ $ \sum_{i=1}^{n}\hat{c_i} = 2 * (k-1) + 0 * 1 = 2k - 2 $ === 1.3. Potential method === Fie $ D_k $ starea dupa k operatii. Starea initiala cand stiva e goala este $ D_0 $ . Definim o functie ne-negativa de potential $ \Phi : States -> ℕ $ Notand costurile amortizate ale unei operatii arbitrare cu $ \hat c_{i} $ si costul sau real cu $ c_i $ , avem de aratat ca: \\ $ \sum_{i=1}^{n}{c_i} \leq \sum_{i=1}^{n}{\hat{c_i}} $ Stim ca: $ \hat{c_i} = c_{i} + \Phi(D_i) - \Phi(D_{i-1}) $ Deci: $ \sum_{i=1}^{n}{\hat{c_i}} = \sum_{i=1}^{n}{c_i} + \Phi(D_n) - \Phi(D_0) $ Acem de ales $ \Phi $ asftel incat $ \Phi(D_0) \leq \Phi(D_n) $ . $ \Phi(D_0) = 0 $ (mereu) Daca in stiva avem $ m $ elemente, acestea au "potentialul" de a fi scoase ulterior cu k operatii $ pop $ sau $ mpop(m) $ : \\ $ \Phi(D) = m $ Calculam costul amortizat al fiecarei operatii:\\ $ \hat c_{push} = c_{push} + \Phi(D_i) - \Phi(D_{i-1}) = c_{push} + (m + 1) - m = c_{push} + 1 = 1 + 1 = 2 $ \\ $ \hat c_{pop} = c_{pop} + \Phi(D_i) - \Phi(D_{i-1}) = c_{pop} + (m - 1) - m = c_{pop} - 1 = 1 - 1 = 0 $ \\ $ \hat c_{mpop(k)} = c_{mpop(k)} + \Phi(D_i) - \Phi(D_{i-1}) = c_{mpop(k)} + (m - k) - m = c_{mpop(k)} - k = k - k = 0 $ ==== 2. Heap ==== === 2.1. Aggregate Method === Fie $ S $ o secventa de $ n $ inserari intr-un heap gol. Pentru a simplifica analiza, dar fara a influenta rezultatul, vom presupune ca $ n = 2^k $, $ k = log_2(n) $. Pe nivelul 0 avem 1 nod (radacina) care necesita maxim 0 swap-uri pentru a ajunge pe pozitia corecta. \\ Pe nivelul 1 avem 2 noduri care necesita maxim 1 swap-uri pentru a ajunge pe pozitia corecta. \\ Pe nivelul 2 avem 4 noduri care necesita maxim 2 swap-uri pentru a ajunge pe pozitia corecta. \\ ... \\ Pe nivelul k avem $ 2^k $ noduri care necesita maxim k swap-uri pentru a ajunge pe pozitia corecta. \\ Pentru a insera un nod in heap, avem nevoie de costul de inserare ($ 1 $) si costul de pozitionare prin swap cu parintii. $ cost(S) = \sum_{i=1}^{n}{1} + \sum_{i=1}^{k}{nodes(i) * swaps(i)} = $ \\ $ = n + \sum_{i=1}^{log_2(n)}{2^i * i} = $ \\ https://www.wolframalpha.com/input?i=sum+j%3D0+to+n+of+j+2%5Ej \\ $ = n + 2(log_2(n) * 2^{log_2(n)} - 2^{log_2(n)} + 1) = $ \\ $ = n + 2(log_2(n) * n - n + 1) = $ \\ $ = n + 2 * log_2(n) * n - 2n + 2 = O(nlog(n)) $ Deci, pentru o singura operatie de insert, avem $ cost(insert) = cost(S) / n = O(nlog(n)) / n = O(log(n)) $ === 2.2. Accounting Method === Pentru fiecare $ insert $, avem nevoie sa luam in considerare: - costul de creare al unui nou nod = $ 1 $ - swap cu parintii = $ log(n) $ Alegem $ \hat c_{insert} = 1 + log(n) = O(log(n)) $ Acest cost este mereu mai mare sau egal decat costul real al unei operatii, dat fiind ca nu toate operatiile au nevoie de $ log(n) $ swap-uri. === 2.3. Potential Method === Fie starile $ D_i $ = starea heap-ului dupa $ i $ operatii $ insert $ Definim o functie ne-negativa de potential $ \Phi : States -> ℕ $ \\ $ \Phi(D_0) = 0 $ \\ $ \Phi(D_i) = $ numarul de valori in heap Calculam costul amortizat: \\ $ \hat{c_i} = c_{i} + \Phi(D_i) - \Phi(D_{i-1}) = c_{i} + 1 $ $ c_{i} $ are un cost $ log(n) + 1 $ dat de numarul de swap-uri maxim + inserarea unui nod in heap. Deci, putem alege $ \hat{c_i} = log(n) + 2 $ ==== 3. Binary Counter ==== === 3.1. Aggregate method === Bitul 0 se schimba la fiecare operatie. \\ Bitul 1 se schimba la fiecare $ 2 $ operatii. \\ Bitul 2 se schimba la fiecare $ 4 $ operatii. \\ ...\\ Bitul 2 se schimba la fiecare $ 2^k $ operatii. \\ Intr-o secventa $ S $ de $ n $ operatii $ increment $, numarul total de modificari de biti este: \\ $ cost(S) = n + n/2 + n/(2^2) + ... + n/(2^k) \leq n / (1 - 1/2) = 2n $ Deci, costul amortizat al unei singure operatii de increment este: $ cost(op) = cost(S) / n = 2n / n = 2 $ === 3.2. Accounting method === Costul real al unei operatii este numarul de biti modificati. Costul amortizat trebuie sa contina: \\ - o schimbare a unui bit din 0 in 1 - o schimbare ulterioara a bitului din 1 in 0 $ \hat c_{increment} = 2$ === 3.3. Potential method === Fie starile $ D_i $ = starea contorului dupa $ i $ operatii $ increment $ Definim o functie ne-negativa de potential $ \Phi : States -> ℕ $ \\ $ \Phi(D_0) = 0 $ \\ $ \Phi(D_i) = $ numarul de biti de $ 1 $ din contor dupa $ i $ operatii $ increment $ Presupunand ca operatia $ i $ reseteaza $ k_i $ biti de 1, costul real al operatiei devine $ c_i = 1 + k_i $. Stim ca $ \hat{c_i} = c_{i} + \Phi(D_i) - \Phi(D_{i-1}) $ Calculam $ \hat{c_i} $ pe un caz simplu: $ 000000 -> 000001 $ \\ $ \hat{c_i} = c_{i} + \Phi(D_i) - \Phi(D_{i-1}) = 1 + 1 - 0 = 2 $ Aratam ca $ \sum_{i=1}^{n}{c_i} \leq \sum_{i=1}^{n}{\hat{c_i}} $ \\ $ \hat{c}_i = c_i + \Phi(F_i) - \Phi(F_{i-1}) => \sum_{i=1}^{n}{\hat{c_i}} = \sum_{i=1}^{n}{c_i + \Phi(F_i) - \Phi(F_{i-1})} = $ \\ $ = \sum_{i=1}^{n}{c_i} + \Phi(F_n) - \Phi(F_{0}) $ $ \Phi(F_n) \geq \Phi(F_{0}) $ se intampla mereu pentru ca numarul de biti de 1 nu poate scadea sub $ 0 $, adica atatia biti $ 1 $ cat sunt in starea $ F_0 $