Zadání semestrálního projektu Algoritmy II. letní semestr 2017/2018 doc. Mgr. Jiří Dvorský, Ph.D. Verze zadání 6. dubna 2018 První verze Obecné pokyny 1. Celkem jsou k dispozici tři zadání příkladů. 2. Každý student má přiděleno jedno zadání. Na webu předmětu Algoritmy II je zveřejněn seznam studentů a jim přiřazených zadání. Kdo by se tam případně nenašel, nechť mě neprodleně kontaktuje emailem. 3. Termín odevzdání 20. května 2018 ve 23:59 Tento termín je konečný a nebude dále posunován. 4. Projekt odevzdáváte přes službu Dropbox do sdíleného adresáře. Odkaz na sdílený adresář Vám bude zaslán na školní email. 5. Projekt odevzdáváte jako zip archiv s řešením (solution) pro vývojové prostředí Visual Studio 2013 a vyšší. 6. Součástí zdrojových kódů Vašeho programu bude programátorská dokumentace ve formě dokumentačních komentářů, zpracovatelných programem Doxygen, viz www.doxygen. org. Vygenerovanou dokumentaci není nutné odevzdávat, postačuje pokud Vámi odevzdaný archiv bude obsahovat konfigurační soubor doxyfile, případné adresáře pro vygenerovanou dokumentaci, vkládané obrázky atd. 7. Upozorňuji, že nestačí jen program odevzdat, ale je nutné své řešení před tutorem obhájit. Termíny obhajoby budou vypsány v systému Edison a budou směrovány do zkouškového období. 8. U odevzdaných řešení se hodnotí v první řadě funkčnost programu a správnost výsledku. Dále se hodnotí složitost použitého algoritmu (čím menší, tím lepší), návrh programu 1
(řekněme rozložení funkcionality programu a dat mezi třídy) a přehlednost zápisu zdrojového kódu. Program, který bude funkční a bude poskytovat správný výsledek, ale bude využívat neefektivní algoritmus, návrh programu bude zmatený a zdrojový kód zapsán šíleně, obdrží minimální počet bodů. Pokud program nebude funkční nebo nebude poskytovat správný výsledek bude hodnocem 0 body. 2
1 Tranzitivní uzávěr Nejprve trochu teorie. Mějme dvě množiny A a B. Kartézským součinem A B množin A a B rozumíme množinu všech uspořádaných dvojic (a,b) takových, že a A a zároveň b B. Například kartézským součinem osmi prvkové množiny se čtyř prvkovou množinou je třiceti dvou prvková množina A = {sedma, osma, devitka, desitka, spodek, svrsek, kral, eso} B = {srdce, listy, kule, zaludy} A B = {(sedma,srdce),...,(sedma,zaludy),(osma,srdce),...,(eso,kule),(eso,zaludy)}. Pokud je množina A shodná s množinou B, pak kartézský součin A A značíme A 2 a mluvíme o kartézské mocnině. Dále si zavedeme pojem binární relace. Opět mějme množiny A a B, binární relací R pak nazýváme podmnožinu kartézského součinu A B, formálně R A B. Binární relace vyjadřuje vztah (relaci) prvků jedné množiny k prvkům v množině druhé. Fakt, že prvek a A je v relaci R s prvkem b B zapisujeme obvykle jako arb. Binární relace mají různé vlastnosti. Jednou z těchto vlastností je tranzitivita relace. Relaci R A 2 nazýváme tranzitivní, právě když platí arb brc arc pro všechny prvky a,b,c A. Například relace být větší, značená běžně jako <, na kartézské mocnině přirozených čísel N 2, je tranzitivní, protože zřejmě platí a < b b < c a < c. Na obrázku 1a je graficky znázorněna relace K M 2 nad množinou M = {a,b,c,d}. Písmena můžou například označovat počáteční písmena jmen Adam, Božena, Cyril a David. Binární relaci K, znázorněnou orientovanými hranami, můžeme slovně zapsat jak vztah být kamarád. Z obrázku jasně vidíme například, že Adam je kamarád Boženy, Božena je kamarádkou Cyrila. Z téhož obrázku je dále patrné, že Adam nemusí být nutně kamarádem Cyrila 1. Neplatí tedy obecně, že akb bkc akc. Binární relace K tedy není tranzitivní. Zajímavou úlohou může být snaha doplnit relaci K tak, aby se stala tranzitivní a zároveň obsahovala nejmenší možný počet vztahů 2. Výsledná relace T (K) je zobrazena na obrázku 1b, nově přidané vztahy jsou znázorněny zelenými šipkami. Takto vytvořená relace T (K) se nazývá tranzitivní uzávěr (angl. transitive closure) relace K. Ve Vašem projektu předpokládejme binární relaci R A 2, kde A je množina přirozených čísel A = {0,1,...,n 1}. Vaším úkolem, s využitím OOP, je: 1. navrhnout a implementovat vhodné datové struktury pro reprezentaci a manipulaci s binární relací R a 2. navrhnout a implementovat algoritmus výpočtu tranzitivního uzávěru pro zadanou binární relaci R. Relace R je uložena v textovém souboru následujícím způsobem: na prvním řádku je uložena hodnota n a 1 Jak je v reálném světě obvyklé, Adam nemusí znát všechny Boženčiny kamarády. 2 Je jasné, že pokud bychom doplnili relaci K na celý kartézský součin, tak relace K bude tranzitivní. Což pro naši ukázkovou relaci znamená, že všichni se kamarádí se všemi. Takové řešení však není asi zajímavé 3
a b a b c c d (a) binární relace K d (b) tranzitivní uzávěr T (K) Obrázek 1: Příklad binární relace a jejího tranzitivního uzávěru na dalších řádcích je vždy uložena dvojice čísel a a b, které náleží do relace R, tedy platí pro ně arb. Výsledný tranzitivní uzávěr T (R) vypište do textového souboru ve stejném formátu. 4
2 Řídké matice V tomto zadání se budeme zabývat speciálním druhem matic. Předpokládejme, že máme dánu reálnou matici A typu m n. Protože matice A je reálná, prvky této matice mohou být libovolná reálná čísla. Zcela specifickou roli v matematice hrají tzv. řídké matice. Řídké matice se typicky vyznačují dvěma vlastnostmi: počet řádků a sloupců může dosahovat obrovských hodnot, i několika miliard, a počet nenulových prvků je naopak velmi malý. Je zřejmé, že řídkou matici můžeme efektivně implementovat uložením pouze nenulových prvků. A dále řídkosti matice můžeme přizpůsobit i maticové operace a provádět tak efektivně operace i s velkými maticemi. Vaším úkolem v tomto projektu je, s využitím objektově orientovaného programování, navrhnout a implementovat efektivní datovou strukturu pro uložení reálné řídké matice A typu m n spolu s vybranými operacemi. Implementace řídké matice bude umožňovat: vytvořit řídkou matici A typu m n a se všemi nulovými prvky, načíst řídkou matici A z textového souboru. Matice A bude uložena následujícím způsobem: 1. na prvním řádku textového souboru jsou tři přirozená čísla m n k, kde m je počet řádků matice A, n je počet sloupců této matice a konečně k je počet nenulových hodnot této matice, 2. na dalších řádcích jsou vždy trojice čísel i j a i,j, kde i je číslo řádku, j je číslo sloupce a a i,j je hodnota prvku matice A na tomto řádku a sloupci. Jako oddělovač je použita mezera či tabulátor. get a set operace pro získání a nastavení prvku na řádku i a sloupci j, metoda vracející počet nenulových prvků matice, metoda pro uložení matice do textového souboru, formát je shodný jako při načítání matice metoda pro vytvoření transponované matice a metoda pro efektivní výpočet Frobeniovy normy. Frobeniova norma matice A je definována jako m n A F = i=1 j=1 Efektivním výpočtem rozumíme výpočet, který pracuje pouze s nenulovými prvky matice A. a 2 i,j 5
3 Indexování textu V tomto projektu se budeme věnovat indexování množiny textových dokumentů. Indexování textových dokumentů se provádí ze stejného důvodu jako indexování záznamů v databázi urychlení vyhledávání. V dnešní době se technologie indexování textových dokumentů nejčastěji aplikují v internetových vyhledávačích na html stránky. Hlavní funkcionalitou textového indexu je nalezení výskytů slova zadaného uživatelem ve všech zaindexovaných dokumentech. Textový index vzniká tzv. lexikální analýzou dokumentu, při které se dokumenty čtou znak po znaku, ze znaků se tvoří slova, která se spolu s identifikačním číslem dokumentu a pozicí slova v textu dokumentu ukládají do vhodných datových struktur. Předpokládejme, že máme vytvořit index pro tyto tři dokumenty: Id dokumentu Text dokumentu 0 computer monitor 1 computer mouse mouse 2 mouse monitor computer Lexikální analýzou těchto dokumentů dostáváme seznam výskytů slov v jednotlivých dokumentech: Slovo Id dokumentu Pozice slova computer 0 0 monitor 0 1 computer 1 0 mouse 1 1 mouse 1 2 mouse 2 0 monitor 2 1 computer 2 2 Z tabulky je zřejmé, že seznam výskytů slov je tříděn podle čísla dokumentu. My však pro vyhledávání potřebujeme mít seznam setříděný podle slov. Změna třídění se v tomto případě historicky nazývá invertování seznamu a vzniklá organizace seznamu všech výskytů slov, jinak řečeno textový index, se pak nazývá invertovaný seznam (angl. inverted list). Pro náš ukázkový příklad dostáváme následující invertovaný seznam: Slovo Výskyty slova computer (0:0), (1:0), (2:2) monitor (0:1), (2:1) mouse (1:1,2), (2:0) Vaším ukolem je, s využitím OOP, navrhnout a implementovat: vhodné datové struktury pro reprezentaci invertovaného seznamu, algoritmus pro indexování množiny dokumentů a algoritmus pro vyhledání všech výskytů zadaného slova v invertovaném seznamu. 6
Jako vstup předpokládejte jeden textový soubor, každý řádek v tomto souboru se považuje za samostatný dokument. Číslování dokumentů (řádků) začíná od 0 a průběžně se zvyšuje o 1. Vstupní text je bez diakritiky, všechna písmena převeďte na malá. Slovo je definováno jako souvislá posloupnost písmen a, b,..., z. Pozice výskytu slova v jednotlivém dokumentu udává prosté pořadí daného slova od začátku dokumentu. Číslování pozic výskytu slova v dokumentu je opět od nuly. Poznámka: V implementaci není nezbytně nutné budovat seznam výskytů slov v jednotlivých dokumentech. Při použití vhodné implementace lze budovat rovnou invertovaný seznam. 7