The Postal Owl

Logged in: Santa Claus (home)   

Algoritmy a datové struktury 2

Back to the course

1. Série domácích úkolů

Deadline: 2022-10-27 14:00 (70 days ago)

Tomáš Domes — modified 2022-10-14 00:35 (83 days ago) — reply

Poznámka: Úloha 1 hovoří o naivním algoritmu vyhledávání jediné jehly v seně, který pro každý znak sena zvlášť otestuje, jestli v něm začíná jehla.

Attachment (pdf)

Santa Claus — 2022-10-25 01:15 (72 days ago) — editreply

1. **Špatný vstup pro naivní algoritmus**

    Nechť $s = a^n$ a $j = a^mc$

	Pak algoritmus poběží $(S-J)J = SJ-J^2 \in \Theta(SJ)$

2. **Nejdelší vlastní prefix**

    Projdeme slovo od začátku a zároveň od konce, končíme při neshodě znaků. Protože se musí jednat o vlastní prefix, nemůžeme vrátit délku celého slova, takže v případě palidromu snížíme délku o jednotku.  
    Prakticky můžeme k řetězci $\alpha$ sestrojit obrácený řetězec $\alpha_{rev}$. Z obou řetězců odstraníme poslední znak a pak vracíme délku shodných prefixů obou řetězců.
    Řetězec takto projdeme dvakrát, algoritmus je lineární. Pamětově je konstantní, protože až na vstup nic neukládáme.

3. **Příliš jehel**

	Uvažme seno $s = a^n$ kde BÚNO $n = 2^i, i \in \mathbb{N}$.  
	K němu uvažme jehly $\iota = \{ a, a^2, a^4, a^8, ..., a^n \}$
	
	Celková délka sena je $n$.
	Součet délek jehel $J = 1 + 2 + 4 + ... + n = 2n - 1 \in \Theta(n)$
	
	Ale celkový počet výskytů bude $n + (n-1) + (n-3) + (n-7) + ... + 1 = n \log(n) - const \cdot n$

4. **Počty výskytů jehel**

	Použijeme AC algoritmus, ale nebudeme procházet zkratkové hrany. Místo toho si v každém stavu automatu uložíme, kolikrát jsme se v něm zastavili. 
	Na konci projdeme celý strom automatu a vždy projdeme všechny zkratkové hrany, součty takto sečteme pro každou jehlu. Pak už zbývá jenom strom projít podruhé
	a pro každý vrchol s jehlou ohlásit počet výskytů. Tyto průchody jsou lineární s počtem jehel, každá zkratková hrana odpovídá jehle.

Tomáš Domes — 2022-10-26 18:43 (70 days ago) — reply

1. Řešení je dobře, ale výpočet úplně nesedí. Např pro S=J máme podle tvého vzorce (S-J)*J čas 0, reálný čas je ale J (nebo S). Asi bys chtěl (S-J+1)*J. Dám ti ale 5b, je to malá chyba.

2. Tady je asi problém s definicí suffixu a prefixu. Obojí se počítá zleva doprava, zatímco ty bereš suffix v opačném směru. Např pro slovo abxyzab je řešením příkladu řetězec "ab".

3. Ok, 5b. Je to pravda, ale pro příště prosím nějak zdůvodni proč je výsledek sumy opravdu takový jaký jsi napsal (i když je pravda že wolfram to spolkne). Navíc se dá jednoduše obejít i bez Wolframu. Stačí nepoužívat nejdelší jehlu. Pro každou ze zbylých jehel platí, že může začínat na prvních n/2 pozicích a tedy počet výskytů všech je alespoň $\frac{n}{2}\cdot(\log(n)-1)$.

4. To je správně, ale je potřeba vysvětlit, jakým způsobem procházíme ten strom když děláme ty součty, aby to fungovalo a zároveň to zabralo lineární čas. 3b.

Points: 13.00

Santa Claus — 2022-10-26 19:23 (70 days ago) — editreply

Díky, můžu to ještě do deadline opravit?

Tomáš Domes — 2022-10-26 19:39 (70 days ago) — reply

> Díky, můžu to ještě do deadline opravit?
jj, určitě to udělej, já si to ale přečtu až po deadlinu, teď nestíhám

Santa Claus — modified 2022-10-27 01:42 (70 days ago) — editreply

2\. Mohli bychom to udělat třeba takto: Spustíme na retězci KMP, tj. jehla i seno budou stejný řetězec, na konci je automat v stavu nalezení jehly, podíváme se, kam z tohoto stavu vede zpětná hrana, ten stav bude příslušet části řetězce, která bude hledaným prefixem i suffixem.

Nalezený stav bude odpovídat prefixu i suffixu, prefixu triviálně proto, že se jedná o prefix jehly, takový máme automat, suffixu proto, že se do tohoto stavu dostaneme skokem po zpětné hraně, a tak jsme ji dříve definovali, jako nejdelší vlastní suffix sena (řetězce), který je prefixem jehly (řetězce). Jedná se o suffix vlastní, tedy to bude i vlastní prefix - délka nebude rovna délce řetězce.

4\. Dovysvětlení průchodu stromem automatu.

Na konci algoritmu projdeme celý strom, vrcholy seřadíme podle vzdálenosti od kořene od největší, vždy skočíme po případné zkratkové hraně a přičteme počet ve vrcholu k počtu v nově dosaženém vrcholu, dál neskáčeme, vezmeme další vrchol. Toto je lineární se součtem délek jehel, stejně jako stavba automatu, z každého stavu skočíme maximálně jednou, každý stav odpovídá písmenu v jehle. Toto bude fungovat, protože vždy, když skáčeme z nějakého vrcholu, už jsme na něj skočili všemi zkratkami - buď to není vrchol s koncem jehly - pak na něj žádná zkratka nevede, nebo je to vrchol s koncem jehly, ale pak všechny zkratky na něj vedoucí musí být ze stavů s delším řetězcem stavu.

Na konci projdeme celý strom a pro vrcholy s konci jehel ohlásíme daný počet, lineární s délkami jehel, nebo s počtem jehel, pokud si předem na tyto vrcholu uchováme odkazy.

Tomáš Domes — modified 2022-11-04 22:04 (61 days ago) — reply

2\. To je správně, jenom podotýkám že je zbytečné algoritmus pouštět. Zpětná hrana vede pořád na stejné místo, puštění algoritmu na tom nic nezmění - stačí postavit automat a podívat se kam vede hrana z posledního stavu.

4\. To je správné řešení. Chybí mi ale informace o tom, jak seřadíme vrcholy podle vzdálenosti od kořene od největšího po nejmenší v lineárním čase. Běžné třídící algoritmy potřebují čas $n \log n$, bylo by vhodné zmínit že použijeme bucket sort. 4.5 b

Points: 19.50

New post (You can use Markdown with KaTeX math here)

Preview: