Dicsőségtabló Beadós programozási feladatok Hallgatói munkák 2017 2018
Szavak kiírása ábécé felett Készítő: Maurer Márton (GI, nappali, 2017) Elméleti háttér Adott véges Ʃ ábécé felett megszámlálhatóan sok szó generálható, csak az n-hosszúakat tekintve Ʃ n darabot találunk. Például G = {a, b} felett G* = {e, a, b, aa, ab, ba, bb, aaa, aab, aba, }. Érdekes kihívás lehet, hogy gépünkön (ügyes algoritmussal) minél nagyobb n-ekre is hatékonyan képesek legyünk ezen szavak előállítására. Algoritmus A szavakat az ábécé betűiből ismétléses variációk segítségével állítjuk elő Programozási környezet, jellemzők Java, NetBeans IDE 8.1 alatt GUI Futási idő, hatékonyság Értelemszerűen az ábécé méretétől és a szavak darabszámától függ, például: G ábécé 0 10 hosszú szavai: ~58 másodperc (2 047 szó) Kiterjesztett magyar ábécé összes 3 hosszú szava: ~47 perc (85 185 db szó) 2
Szavak kiírása ábécé felett A program felülete, futási kép és eredmény (részletek) Ábécé kiválasztása, szavak hosszának megadása Ábécé módosítása Szavak generálás közben, végeredmény 3
Szavak kiírása ábécé felett A kód bemutatása 1. listagenerálás() metódus: összes olyan szó generálása, ami az intervallumba esik Variálás(String[] karakterek, String[] szó, int hely): egy X hosszú szót generál (ism. variáció) 4
Szavak kiírása ábécé felett A kód bemutatása 2.: ábécé fájlok írása (háttértárra) és beolvasása FájlKiír(int hányadik): kiírja a megadott ábécét egy <ábécé név>.abc fájlba FájlOlvas(): ábécé fájlt (*.abc) olvas az ABC könyvtárból 5
Szavak kiírása ábécé felett Egyéb érdekesség, továbbfejlesztési lehetőség A program jelenleg hibázik, ha túllépjük az Integer adattípus felső korlátját (2 147 483 647) Ez a tömbök (megjelenítés a JList ezt használja) és a listák elemeinek elérésekor probléma a túlindexelés miatt (get, arraylist és tömb elemekre) (A bemutatott részletek forrása: Java Platform, Standard Edition 8 API) Fejlesztési lehetőségek Nagyobb adattárolók használata A többdim. adattárolás megoldja a több szó memóriában való tárolását (feltéve, hogy elfér), de a megjelenítés problémáját nem, mert a JList csak egydim. tömböt fogad el Szöveges fájl használata Ilyenkor elvileg csak memória, ill. a háttértár korlátozhat) 6
Szavak kiírása ábécé felett Készítő: Révész Roland (MI, nappali, 2017) Elméleti háttér Adott véges Ʃ ábécé felett megszámlálhatóan sok szó generálható, csak az n-hosszúakat tekintve Ʃ n darabot találunk. Például V = {a, b, c} felett V* = {e, a, b, c, aa, ab, ac, ba, bb, bc, ca, cb, cc, aaa, aab, abc, }. Érdekes kihívás lehet, hogy gépünkön (ügyes algoritmussal) minél nagyobb n-ekre is hatékonyan képesek legyünk ezen szavak előállítására. Algoritmus Minden lehetőséget listázunk a lexikografikus rendezés szerint (részletezve lásd a köv. oldalakon) Programozási környezet, jellemzők Delphi 4 fejlesztőkörnyezet alatt, karakteres interfész Futási idő, hatékonyság Értelemszerűen az ábécé méretétől és a szavak darabszámától függ, például: G ábécé 0 16 hosszú szavai (131 071 szó): 20 másodperc alatt; A magyar ábécé feletti szavak 4 hosszig (1 501 885 szó): 3 perc alatt 7
Szavak kiírása ábécé felett Az algoritmus bemutatása ABC a megadott ábécé; L az ábécé betűinek száma; i és j számlálók; k segédváltozó; s szövegváltozó Az ABC ábécé betűiből L N darab N hosszú szó képezhető Ha i kezdetben 0 és ABC-t nullától indexeljük, akkor az i. szó jobbszélső betűje az ABC (i mod L)-edik eleme lesz Azaz a szimbólumokat sorrendben használjuk fel, és ha elfogynak, akkor újrakezdjük az elejéről (mint a számoknál) Jobbról a 2. betű is hasonlóan viselkedik, de az csak minden L-edik lépésben változik A j-edik betű (j 0-tól indul) az ABC (i div L j mod L)-edik eleme Ha i-t L-es számrendszerben írjuk le, akkor annak jegyei az egyes betűk indexei Példa: ABC = {a, b, c}, N = 2 i = 0 esetén: 00 aa i = 1 esetén: 01 ab i = 2 esetén: 02 ac i = 3 esetén: 10 ba, i = 4 esetén: 11 bb, i = 5 esetén: 12 bc i = 6 esetén: 20 ca, i = 7 esetén: 21 cb, i = 8 esetén: 22 cc 8
Szavak kiírása ábécé felett Az algoritmus bemutatása (folyt.) Lépések Változat: k segédváltozó helyett i-t használjuk az előállításhoz 9
Szavak kiírása ábécé felett Az algoritmus bemutatása (folyt.) Forráskód 10
Szavak kiírása ábécé felett Futási kép és eredmény Az ábécét és a maximális szóhosszt parancssori paraméterként kell megadni Az előbbit egy sztringként, elválasztás nélkül A szóhossz 1 bájtos előjel nélküli A program minden szót kiír a megadott hosszig Ha túl kevés paramétert adunk meg, akkor kiírja a helyes használat módját 11
Determinisztikus véges automaták szimulációja Készítő: Maurer Márton (GI, nappali, 2017) Elméleti háttér Determ. véges automata (DVA) egy rendezett ötös; M = (K, δ, Ʃ, s, F), ahol K Állapotok halmaza δ Átmeneti függvény (teljesen definiált) Ʃ Ábécé s Kezdő állapot F Elfogadó állapotok halmaza A DVA szavakat olvas végig, és ezeket elfogadja, vagy elutasítja. Így minden DVA-hoz tartozik egyértelműen egy konkrét elfogadott nyelv (a DVA nyelvfelismerő eszköz). Egy DVA futtatása viszonylag egyszerűen megvalósítható számítógéppel; hosszú feldolgozandó szavakra is rövid idő alatt eredményt kaphatunk. Algoritmus A szó betűit beolvasva lépkedünk az egyes állapotok között, majd az utolsó karakter beolvasása után döntünk, hogy a szó a felismert nyelvhez tartozik-e 12
Determinisztikus véges automaták szimulációja Programozási környezet, jellemzők Java, NetBeans IDE 8.1 alatt GUI Futási idő, hatékonyság Az automata futásidejét a feldolgozandó szó hossza határozza meg. Mondhatjuk, hogy az algoritmus O(n)-es, ha egy összetett lépésnek tekintjük egy betű feldolgozását. A program felülete (részletek) Automata kiválasztása és a feldolgozandó szó megadása Automata gráfjának megjelenítése 13
Determinisztikus véges automaták szimulációja A program felülete (részletek, folyt.) Az automata lehetséges válaszai (eredmények; adott szavak beolvasására, elfogadására) Az elfogadáshoz vezető konfiguráció-sorozat 14
Determinisztikus véges automaták szimulációja A program felülete (részletek, folyt.) Új automata felvétele 15
Determinisztikus véges automaták szimulációja A kód bemutatása 1. AutomataFuttat(): lefuttatja az automatát és döntést hoz a szóról, hogy a nyelvhez tartozik-e 16
Determinisztikus véges automaták szimulációja A kód bemutatása 2.: automata kirajzolás Visualize_Directed_Graph(Állapot[] állapotok, Állapot kezdő, Állapot[] elfogadó, ArrayList<Átmenet> átmenetek): A megadott automata kirajzolása egy irányított gráfban Részlet a gráf csúcsainak létrehozása 17
Determinisztikus véges automaták szimulációja A kód bemutatása 3.: automata kirajzolás (folyt.) Visualize_Directed_Graph( ), folyt. Részlet azonos helyről induló és azonos pontba érkező élek egyesítése; élek kezdő, végpontjainak és címkéinek felvétele; élek hozzáadása a gráfhoz
Determinisztikus véges automaták szimulációja A kód bemutatása 4.: automata kirajzolás (folyt.) Visualize_Directed_Graph( ), folyt. Részlet gráf formázási leírások (jobbra lásd: jelek magyarázata) 19
Determinisztikus véges automaták szimulációja Példaautomata, futtatás A következő M automata azon szavakat fogadja el, amelyek tartalmazzák az aba részszót M gráfja, K és δ, G ábécé q 0 kezdőállapot (négyzet), q 3 végállapot (zöld)
Determinisztikus véges automaták szimulációja M automata a memóriában Piros K; bordó δ; lila egy átmenet 21
Determinisztikus véges automaták szimulációja M automata működése, futási eredmények Az aaaaaaaa és a bababa szavak feldolgozásának eredménye és a számítási sorozatok q 3 végállapot 22
Determinisztikus véges automaták szimulációja Egyéb érdekességek A gráf kirajzolásához a JUNG2 (2.0.1) JAVA környezetben fejlesztett gráfkezelő könyvtárat használja a program A Visualize_Directed_Graph()-ot (és a hozzá szükséges adattípusokat) eredetileg Niraj Kumar készítette (a kód az interneten elérhető). Ennek a kódnak egy módosítása található a programban. A program használja a Szavak kiírása ábécé felett program kódjának egy részét (az ábécét kezelő modult) Korlátok A program a véges automatákat ésszerű korlátok figyelembe vételével kezeli; az alábbiak szerint: állapotok (tömb), elfogadási állapotok (tömb), átmenetek (ArrayList), ábécé karakterek (ArrayList), szavak (String/LinkedList), ill. számítási sorozatok (tárolás ArrayList; megjelenés tömb) A tömb, az ArrayList és a LinkedList egyaránt Integer adatelérést használnak. Ha az Integer adattípus felső korlátján (2 147 483 647) kívül indexelünk, akkor a program megáll. 23
NVA DVA átalakítás Készítő: Maurer Márton (GI, nappali, 2017) Elméleti háttér A nemdet. véges automata (NVA) determ. párjához hasonlóan egy rendezett ötös; M = (K,, Ʃ, s, F), ahol K Állapotok halmaza Átmeneti reláció (az Elements könyv értelmezése szerint) Ʃ Ábécé s Kezdő állapot F Elfogadó állapotok halmaza Az NVA a DVA-hoz hasonlóan szavakat olvas, és ezeket elfogadja, vagy elutasítja. ( NVA-hoz tartozik egyértelműen egy konkrét elfogadott nyelv.) Az NVA-nak azonban a DVA-tól eltérően nem kell teljesen definiáltnak lennie, és itt üres átmenetek (e-átm.), ill. (esetleg) sztringeket tartalmazó átmenetek is megengedettek. Mindezek miatt az NVA általában tömörebben reprezentálja ugyanazt a felismerő kapacitást, mint az ekvivalens DVA, viszont hagyományos módon nem futtatható (úgy, mint egy DVA). Ezért indokolt sok esetben az NVA átalakítása egy ekvivalens DVA-vá. 24
NVA DVA átalakítás Algoritmus (fő lépések) Szavakat tartalmazó átmenetek betű átmenetekre bontása (ha találhatók ilyenek) Új állapotok felvétele és betű átmenetek hozzáadása Új DVA kezdő állapotának meghatározása NVA kezdő állapotához tartozó e-átmenetek vizsgálata (első DVA állapot) DVA átmeneteinek meghatározása Hova lehet eljutni a Ʃ ábécé betűivel Majd ezekből az állapotokból e-átmenettel hova lehet még tovább jutni Elfogadó állapotok létrehozása Az új DVA állapotaiból azok lesznek elfogadó állapotok, amelyek tartalmazzák az eredeti NVA valamelyik elfogadó állapotát Programozási környezet, jellemzők Java, NetBeans IDE 8.1 alatt GUI Futási idő, hatékonyság Az új DVA állapotainak számától függ (igen rossz esetben exponenciális) Az új DVA állapotainak maximális száma 2 K, ahol K az NVA áll.nak száma (a DVA teljesen definiált lesz) 25
NVA DVA átalakítás A kód bemutatása 1. DVAÁtalakítás(automata nfa): célja az NVA-t átalakítani egy azonos nyelvet elfogadó DVA-vá Részlet: Sztring átmenetek betű átmenetté konvertálása (1. rész, új állapotok hozzáadása) 26
NVA DVA átalakítás A kód bemutatása 2. DVAÁtalakítás(automata nfa) Részlet: Sztring átmenetek betű átmenetté konvertálása (2. rész, a szükséges új átmenetek hozzáadása) 27
NVA DVA átalakítás A kód bemutatása 3. DVAÁtalakítás(automata nfa) Részlet: DVA kezdő állapotának meghatározása 28
NVA DVA átalakítás A kód bemutatása 4. DVAÁtalakítás(automata nfa) Részlet: Új állapotok és átmenetek létrehozása 29
NVA DVA átalakítás A kód bemutatása 5. DVAÁtalakítás(automata nfa) Részlet: Elfogadó állapotok meghatározása, az új automata létrejön 30
NVA DVA átalakítás A működés szemléltetése 1. Adott a lenti automata (NVA), amely e-átmenetet és sztringes átmenetet egyaránt tartalmaz Ezzel a konkrét automatával bemutatjuk az átalakítási lépéseket, először a hagyományos módon, majd a programmal 31
NVA DVA átalakítás A működés szemléltetése 2. 1. lépés: sztringes átmenetek felbontása Két új állapot keletkezik (q3 és q4) 2. lépés: DVA kezdő állapotának meghatározása Eredeti M NVA kezdő állapota: q0 q0-ból nem vezet ki e-átmenet, így az új DVA kezdő állapota q0 lesz (Q0 = {q0}) 32
NVA DVA átalakítás A működés szemléltetése 3. 3. lépés: állapot átmenetek vizsgálata Kérdés: a DVA egy adott állapotából hova tudunk eljutni az NVA átmeneteivel, ill. innen vezet-e még tovább e-átmenet Ha egy átmenet üres, akkor az üres állapotba érünk (csapda, ez is felveendő) δ({q0}, a) = E(q4) = {q4} δ({q0}, b) = E(q1) E(q3) = {q1, q3} δ({q4}, a) = E(q1) = {q1} δ({q4}, b) = üres δ({q1, q3}, a) = E(q1) = {q1} δ({q1, q3}, b) = = E(q0) E(q2) = {q0, q2} δ({q1}, a) = üres δ({q1}, b) = = E(q0) E(q2) = {q0, q2} δ(üres, a) = üres δ(üres, b) = üres δ({q0, q2}, a) = E(q4) = {q4} δ({q0, q2}, b) = {q1, q3} 33
NVA DVA átalakítás A működés szemléltetése 4. 4. lépés: elfogadó állapotok megkeresése Azok lesznek a DVA-ban elfogadó állapotok, amelyek tartalmazzák az eredeti NVA elfogadó állapotait Eredeti NVA: F = {q2} Új DVA: F = {{q0, q2}} 34
NVA DVA átalakítás A működés szemléltetése 5. Az átalakítás eredménye 35
NVA DVA átalakítás A működés szemléltetése 6. Átalakítás a programmal 36
NVA DVA átalakítás A működés szemléltetése 7. Az új automata munka közben Az új DVA segítségével ellenőrizzük egy adott szó végigolvasását: aabbab 37
NVA DVA átalakítás Egyéb érdekességek, megjegyzések A vonatkozó tételből következik, hogy az előállított új DVA valóban ekvivalens az eredeti NVA-val (ugyanazt a nyelvet ismerik fel) A program nem feltétlenül a legkisebb állapotszámú DVA-t találja meg az adott NVA-hoz (minimálautomata konstrukció még nincs beépítve) Ez az átalakító program kisebb adattárolási módosítások mellett beépíthető a Determinisztikus véges automaták szimulációja programba (előző program), így kiterjeszthető a program funkcionalitása Az irányított gráfok megjelenítésére szolgáló modulra ugyanazok a megjegyzések érvényesek, mint a Determinisztikus véges automaták szimulációja programnál Korlátok Hasonló megjegyzések írhatók, mint a Determinisztikus véges automaták szimulációja programnál 38