Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
|
aa:lab:8 [2021/11/29 12:02] dmihai |
aa:lab:8 [2025/12/04 12:08] (current) mihnea.gheorghe fix notation consistency |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== Reduceri polinomiale ====== | + | ====== Arbori Binari de Căutare ====== |
| - | Realizați următoarele reduceri polinomiale: | + | Un **arbore binar de căutare (BST)** este o structură de date arborescentă în care, |
| + | pentru orice nod de valoare \(x\), toate valorile din subarborele stâng sunt | ||
| + | \(< x\), iar toate din cel drept sunt \(> x\). În cadrul acestui laborator vom | ||
| + | pune inegalitatea parțială pe subarborele stâng (\(\le x\)). Această | ||
| + | proprietate permite căutări eficiente, în medie în timp \(O(\log n)\), și | ||
| + | stă la baza multor algoritmi și structuri de date. | ||
| - | * $ Partioning \le_p Subset-Sum$ | + | <note> |
| - | * $ Subset-Sum \le_p Partioning$ | + | Reamintim definiția TDA-ului pentru un arbore binar abstract: |
| - | * $ SAT \le_p 3-SAT$ | + | |
| - | * $ 3SAT \le_p k-Clique$ | + | \( \text{Nil}: \mathrm{BTree} \)\\ |
| - | * $ 3SAT \le_p k-Vertex-Cover$ | + | \( \text{Node}: \mathbb{E} \times \mathrm{BTree} \times \mathrm{BTree} \to \mathrm{BTree} \) |
| + | |||
| + | |||
| + | unde \(\mathbb{E}\) este o [[https://en.wikipedia.org/wiki/Partially_ordered_set|mulțime parțial ordonată]]. | ||
| + | Pentru simplitate vom folosi \(\mathbb{N}\), mulțimea numerelor naturale, însă putem lucra | ||
| + | cu orice mulțime peste care este definită o relație de ordine \(\le\). | ||
| + | </note> | ||
| + | |||
| + | ==== Definiția operatorului \(\mathrm{isBST}\) ==== | ||
| + | |||
| + | \( \mathrm{isBST} : \mathrm{BTree} \to \mathrm{Bool} \\ | ||
| + | \mathrm{isBST}(t) = \mathrm{isBSTBetween}(t, -\infty, +\infty) \\ | ||
| + | \mathrm{isBSTBetween} : \mathrm{BTree} \times \overline{\mathbb{E}} \times \overline{\mathbb{E}} \to \mathrm{Bool} \\ | ||
| + | \mathrm{isBSTBetween}(\mathrm{Nil}, lo, hi) = \text{true} \\ | ||
| + | \mathrm{isBSTBetween}(\mathrm{Node}(x,l,r), lo, hi) = (lo \le x \le hi) | ||
| + | \;\land\; | ||
| + | \mathrm{isBSTBetween}(l, lo, x) | ||
| + | \;\land\; | ||
| + | \mathrm{isBSTBetween}(r, x, hi). \) | ||
| + | |||
| + | unde \(\overline{\mathbb{E}} = \mathbb{E} \cup \{-\infty, +\infty\}\). | ||
| + | |||
| + | Elementele \(-\infty\) și \(+\infty\) extind domeniul astfel încât: | ||
| + | |||
| + | \( -\infty < x < +\infty,\forall x \in \mathbb{E}. \) | ||
| + | |||
| + | |||
| + | |||
| + | ==== Exerciții ==== | ||
| + | 1. Scrieți axiomele pentru următorii operatori: | ||
| + | |||
| + | * $ {\mathrm{insert} : \mathbb{E} \times \mathrm{BTree} \to \mathrm{BTree} } $ | ||
| + | * $ {\mathrm{min} : \mathrm{BTree} \to \mathbb{E} } $ | ||
| + | * $ {\mathrm{max} : \mathrm{BTree} \to \mathbb{E} } $ | ||
| + | |||
| + | 2. Completați fragmentul de cod Python pentru calculul drumului mediu în găsirea unui element x | ||
| + | într-un Arbore Binar de Căutare construit pe baza operatorului $ {\mathrm{insert}} $ din exercițiul anterior: | ||
| + | |||
| + | <file python bst_path.py> | ||
| + | import random | ||
| + | |||
| + | class Node: | ||
| + | def __init__(self, x): | ||
| + | self.x = x | ||
| + | self.left = None | ||
| + | self.right = None | ||
| + | |||
| + | def insert(root, x): | ||
| + | # TODO: inserați x în arbore | ||
| + | pass | ||
| + | |||
| + | def search_path_length(root, x): | ||
| + | # TODO: calculați lungimea drumului până la x | ||
| + | pass | ||
| + | |||
| + | def average_search_path(n): | ||
| + | """Construiește un BST dintr-o permutare aleatoare și măsoară media.""" | ||
| + | perm = list(range(1, n + 1)) | ||
| + | random.shuffle(perm) | ||
| + | |||
| + | root = None | ||
| + | for x in perm: | ||
| + | root = insert(root, x) | ||
| + | |||
| + | lengths = [search_path_length(root, x) for x in perm] | ||
| + | return sum(lengths) / n | ||
| + | |||
| + | def experiment(trials=2000, n=100): | ||
| + | total = 0 | ||
| + | for _ in range(trials): | ||
| + | total += average_search_path(n) | ||
| + | return total / trials | ||
| + | |||
| + | for n in [10, 20, 50, 100, 200, 500, 1000]: | ||
| + | avg = experiment(trials=1000, n=n) | ||
| + | print(f"n = {n} → lungime medie ≈ {avg:.3f}") | ||
| + | </file> | ||
| + | |||
| + | Rezultatul teoretic: | ||
| + | |||
| + | \( | ||
| + | E[L] = \tfrac{2 (n + 1)}{n} (H_{n+1} - 1) - 1 | ||
| + | = \tfrac{2 (n + 1)}{n} (\tfrac{1}{2} + \tfrac{1}{3} + \dots + \tfrac{1}{n} + \tfrac{1}{n+1}) -1 | ||
| + | \) | ||
| + | |||
| + | Cum ar putea fi îmbunătățit drumul mediu și care este acesta pentru un arbore echilibrat? | ||
| + | |||
| + | |||
| + | 3. Demonstrați (prin inducție structurală) că următoarele păstrează invariantul \(\mathrm{isBST}\): | ||
| + | |||
| + | * $ {\mathrm{insert}} $ | ||
| + | * $ {\mathrm{delete}} $ | ||
| + | |||
| + | <note> | ||
| + | Soluțiile acestui laborator se găsesc [[https://ocw.cs.pub.ro/ppcarte/doku.php?id=aa:lab:sol:8|aici]] | ||
| + | </note> | ||