Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
aa:lab:5 [2023/11/11 22:29]
vlad.juja
aa:lab:5 [2025/11/01 11:48] (current)
codrut_eduard.bicu
Line 1: Line 1:
-====== Notații asimptotice ======+===== Analiza Probabilistă în Hashing ​=====
  
-<note important>​Solutii:[[https://​drive.google.com/​file/​d/​1FZro37pN3XaHOAZUK2ttSy1VR1yKMz83/​view?​usp=sharing]]</​note>​+În acest laborator vom explora comportamentul probabilist al hashing-ului și fenomenele care apar din cauza coliziunilor. ​  
 +Vom lucra pe două exemple simple care ilustrează concepte teoretice importante:
  
-$ \Theta(f(n)) = \{ g: \mathbb{R}^{+} \rightarrow \mathbb{R}^{+}\ |\  +  * **Paradoxul zilelor de naștere** — probabilitatea unei coliziuni într-un spațiu finit de valori; 
-\begin{array}{l} +  * **Problema colecționarului de cupoane** — timpul așteptat până acoperim toate cazurile posibile.
-\exists c_1, c_2 \in \mathbb{R}^+\cr +
-\exists n_0 \in \mathbb{N} +
-\end{array}\  +
-such\ that\ \forall\ n \ge n_0,\ \ c_1f(n) \le g(n) \le c_2f(n) \}$+
  
-{{:​aa:​lab:​theta_fn.png|}}+----
  
-$ O(f(n)) ​\{ g: \mathbb{R}^{+} \rightarrow \mathbb{R}^{+}\ |\  +==== Context ====
-\begin{array}{l} +
-\exists c \in \mathbb{R}^+\cr +
-\exists n_0 \in \mathbb{N} +
-\end{array}\  +
-such\ that\ \forall\ n \ge n_0,\ \  +
-0 \le g(n) \le cf(n) \}$+
  
-{{:​aa:​lab:​o_fn.png|}}+În hashing, fiecare element este atribuit aleatoriu unui dintre cele ( k ) sloturi. ​  
 +Problemele pe care le studiem astăzi au aplicații directe în analiza performanței tabelelor hash.
  
-$ \Omega(f(n)) = \{ g: \mathbb{R}^{+} \rightarrow \mathbb{R}^{+}\ |\  +----
-\begin{array}{l} +
-\exists c \in \mathbb{R}^+\cr +
-\exists n_0 \in \mathbb{N} +
-\end{array}\  +
-such\ that\ \forall\ n \ge n_0,\ \  +
-0 \le cf(n) \le g(n) \}$+
  
-{{:aa:​lab:​omega_fn.png|}}+=== Exemplul 1Paradoxul zilelor de naștere ===
  
-$ o(f(n)) = \{ g: \mathbb{R}^{+} \rightarrow \mathbb{R}^{+}\ |\  +Scenariu: avem ( n ) persoane și ( k = 365 zile posibile.  ​ 
-\begin{array}{l} +Dorim să aflăm probabilitatea ca cel puțin două persoane să aibă aceeași zi de naștere.
-\forall c \in \mathbb{R}^+\cr +
-\exists n_0 \in \mathbb{N} +
-\end{array}\  +
-such\ that\ \forall\ n \ge n_0,\ \  +
-0 \le g(n) \le cf(n) \}$+
  
-$ \omega(f(n)) = \{ g\mathbb{R}^{+} \rightarrow \mathbb{R}^{+}\ |\  +Formula teoretică este:
-\begin{array}{l} +
-\forall c \in \mathbb{R}^+\cr +
-\exists n_0 \in \mathbb{N} +
-\end{array}\  +
-such\ that\ \forall\ n \ge n_0,\ \  +
-0 \le cf(n) \le g(n) \}$+
  
-===== Syntactic sugars ======+$$ 
 +P(\text{coliziune}) ​1 - \frac{k!}{(k-n)! \, k^n} 
 +$$
  
-Notațiile asimptotice sunt adesea folosite pentru a ne referi la funcții arbitrare cu o anumită creștere. Pentru simplitate, putem scrie //expresii aritmetice//​ astfel:+Codul de mai jos simulează fenomenul:
  
-$ f(n) = \Theta(n) + O(\log(n)) $+<file python paradoxul_nasterilor.py>​ 
 +import random
  
-Care trebuie citită: $math[\exists g \in \Theta(n)și $math[\exists h \in O(\log(n))] a.î. $math[f(n) = g(n) + h(n),\ \forall n \in \mathbb{R}^{+}].+def paradox_zile_nastere(trials=10000,​ grup=23, zile=365)
 +    """​Estimează probabilitatea ca două persoane să aibă aceeași zi de naștere."""​ 
 +    count = 0 
 +    for _ in range(trials): 
 +        zile_aleatoare = [random.randint(1, zilefor _ in range(grup)] 
 +        if len(zile_aleatoare!len(set(zile_aleatoare)): 
 +            count += 1 
 +    return count / trials
  
-Putem de asemenea scrie //​ecuații//:​+for n in [10, 20, 23, 30, 40, 50]: 
 +    p = paradox_zile_nastere(grup=n) 
 +    print(f"​Grup ​de {n} persoane → Probabilitate ≈ {p:​.3f}"​) 
 +</file>
  
-$ \Theta(n^2) = O(n^2) + o(n)$+**Întrebări:​** 
 +  1. Pentru ce valoare a lui ( n ) probabilitatea depășește 0.5? 
 +  ​2. Cum se aseamănă acest fenomen cu coliziunile dintr-tabelă hash?
  
-Care ar trebui citite: $math[\forall f \in \Theta(n^2),​\ \exists g \in O(n^2)] și $math[\exists h \in o(n)] a.î. $math[f(n) = g(n) + h(n),\ \forall n \in \mathbb{R}^{+}].+----
  
-Observați că ecuațiile nu sunt simetrice și ar trebui citite ​de la stânga la dreapta. De exemplu:+=== Exemplul 2: Problema colecționarului ​de cupoane ===
  
-$\Theta(n) = O(n)$+Scenariu: avem ( n ) cupoane distincte. ​  
 +La fiecare pas tragem unul aleator ​(uniform).   
 +Dorim să aflăm câte extrageri sunt necesare în medie până le avem pe toate.
  
-Deși e adevărat că, pentru orice funcție ​$math[\Theta(n)există o funcție egală în $math[O(n)], putem vedea că există funcții în $math[O(n)] pentru care nu există niciun corespondent în $math[\Theta(n)].+Rezultatul teoretic: 
 +$
 +E[T= n H_n = n(1 + \tfrac{1}{2} + \tfrac{1}{3} + \dots + \tfrac{1}{n}) 
 +$$
  
-Ca regulă, fiecare notație asimptotică din stânga unui egal, ar trebui citită ca o funcție **cuantificată universal** ($math[\forall f]) din acea clasă, iar fiecare notație asimptotică din dreapta unui egal ar trebui citită ca o funcție **cuantificată existențial** ​ ($math[\exists g]) din clasa respectivă.+Simulare:
  
-$\left(\frac{\omega(n^2)}{\Theta(n)}\right) = \Omega(n) + o(n)$+<file python cupoane.py>​ 
 +import random
  
-$math[\forall f \in \omega(n^2)\ and\ +def colector_cupoane(n, incercari=500): 
- \forall g \in \Theta(n),\ \exists h \in \Omega(n)] și $math[\exists j \in o(n)]  a.î. +    """​Returnează numărul mediu de extrageri până la colectarea tuturor cupoanelor."""​ 
-$math[\left(\frac{f(n)}{g(n)}\right) =  +    total = 0 
-h +    for _ in range(incercari)
-(n) + j(n),\ \forall n \in \mathbb{R}^{+}]+        colectate = set() 
 +        pasi = 0 
 +        while len(colectate< n: 
 +            colectate.add(random.randint(0, n-1)) 
 +            pasi +1 
 +        total += pasi 
 +    ​return total / incercari
  
 +for n in [10, 50, 100]:
 +    estimat = colector_cupoane(n)
 +    print(f"​n = {n}: medie ≈ {estimat:​.2f}"​)
 +</​file>​
  
-===== Exerciții ===== +**Întrebări:** 
-<​note>​ +  1Cum crește numărul ​așteptat de extrageri odată cu ( n )? 
-În continuare, aveti un {{:aa:​lab:​lab5notatii.pdf|}} pentru ​va ajuta la rezolvări. +  2. Ce analogie există între această problemă și procesul de „umplere” a tuturor sloturilor într-o tabelă hash?
-</​note>​+
  
-1. Dați exemple de câte o funcție din următoarele clase de complexitate:​+----
  
-  * $ O(n)$ +==== Rezumat ====
-  * $ \Omega(log(n))$ +
-  * $ \Theta(n^2)$ +
-  * $ \omega(\frac{1}{n})$ +
-  * $ o(3^n)$+
  
-2. Pentru fiecare din perechile de mai jos, dați un exemplu concret de constante pentru care inegalitățile implicate în definiția clasei de complexitate sunt adevărate:​ +  ​Hashing-ul se poate analiza folosind concepte probabiliste simple.   
- +  * Paradoxul zilelor de naștere arată cât de rapid apar coliziunile.   
-  ​$ log(n) \in o(\sqrt n)$ +  * Problema colecționarului ​de cupoane arată cât de lent se „umple” complet un spațiu finit.  ​
-  * $ 100n^2 \in O(2^n)$ +
-  * $ 0.001n^3 \in \Omega(20 \sqrt n)$ +
-  * $ 10n \in \Theta(n)$ +
-  * $ n \in \Theta(10n)$ +
- +
-3Găsiți două funcții $ f$ și $ g$, astfel încât: +
- +
-  * $ f(n) = O(g^2(n))$ +
-  * $ f(n) = \omega(\log(g(n)))$ +
-  * $ f(n) = \Omega(f(n)\cdot g(n))$ +
-  * $ f(n) = \Theta(g(n)) + \Omega(g^2(n))$ +
- +
-4. Verificați valoarea ​de adevăr a următoarelor propoziții:​ +
- +
-  * $ \sqrt{n} \in O(log(n))$ +
-  * $ log(n) \in O(log(log(n)))$ +
-  * $ n \in O(log(n)\cdot\sqrt{n})$ +
-  * $ n + log(n) \in \Theta(n)$ +
-  * $\log(n\cdot \log(n))\in\Theta(log(n))$ +
-  * $\sqrt{n}\in\omega(\log(n))$ +
- +
-==== Exerciții - syntactic sugars ==== +
- +
- +
-5. Aduceți următoarele la o formă simplă (o clasă de complexitate ce depinde de o anume funcție): +
- +
-  * $ \frac{O(n\sqrt{n})}{\Theta(n)} = \ldots$ +
-  * $ \frac{\Theta(n)}{O(\log(n))} = \ldots$ +
-6Demonstrați/​infirmați următoarele propoziții:​ +
- +
-  * $ f(n) = \Omega(\log(n)) \land g(n)=O(n) \implies f(n)=\Omega(\log(g(n))$ +
-  * $ f(n) = \Omega(\log(n)) \land g(n)=O(n) \implies f(n)=\Theta(\log(g(n))$ +
-  * $ f(n) = \Omega(g(n)) \land g(n)=O(n^2) \implies \frac{g(n)}{f(n)}=O(n)$+