315
Írta: Kurdi Zsombor ALGORITMUSOK OPTIMÁLIS MEGVALÓSÍTÁSA PÁRHUZAMOS KÖRNYEZETBEN PÁRHUZAMOS SZÁMÍTÁSTECHNIKA MODUL PROAKTÍV INFORMATIKAI MODULFEJLESZTÉS Lektorálta: oktatói munkaközösség 1

Írta: Kurdi Zsombor - tankonyvtar.hu · KULCSSZAVAK: algoritmus, párhuzamosítás, kölcsönös kizárás, programozási tételek, rendezések, keresések, elosztott adatszerkezetek,

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

  • Írta: Kurdi Zsombor

    ALGORITMUSOK OPTIMÁLIS MEGVALÓSÍTÁSA PÁRHUZAMOS KÖRNYEZETBEN

    PÁRHUZAMOS SZÁMÍTÁSTECHNIKA MODUL

    PROAKTÍV INFORMATIKAI MODULFEJLESZTÉS

    Lektorálta: oktatói munkaközösség

    1

  • COPYRIGHT: 2011-2016, Kurdi Zsombor, Óbudai Egyetem, Neumann János Informatikai Kar

    LEKTORÁLTA: oktatói munkaközösség

    Creative Commons NonCommercial-NoDerivs 3.0 (CC BY-NC-ND 3.0) A szerző nevének feltüntetése mellett nem kereskedelmi céllal szabadon másolható, terjeszthető, megjelentethető és előadható, de nem módosítható.

    TÁMOGATÁS: Készült a TÁMOP-4.1.2-08/2/A/KMR-2009-0053 számú, “Proaktív informatikai modulfejlesztés (PRIM1): IT Szolgáltatásmenedzsment modul és Többszálas processzorok és programozásuk modul” című pályázat keretében

    KÉSZÜLT: a Typotex Kiadó gondozásában

    FELELŐS VEZETŐ: Votisky Zsuzsa

    ISBN 978-963-279-559-1

    2

    http://www.typotex.hu/

  • KULCSSZAVAK: algoritmus, párhuzamosítás, kölcsönös kizárás, programozási tételek, rendezések, keresések, elosztott adatszerkezetek, Gauss elimináció, Fourier transzformáció, gráfalgoritmusok, tömörítés, titkosítás, mintaillesztés, geometriai algoritmusok ÖSSZEFOGLALÓ: A tananyag leggyakoribb algoritmusok párhuzamosításának kérdésével foglalkozik. Az algoritmusok elemzésével és párhuzamosításával foglalkozó elméleti bevezető után a gyakorlatokra tevődik át a hangsúly. Ez az egyszerűbb algoritmusokkal, a programozási tételekkel – mint például a minimum/maximum keresés, számlálás, összegzés – kezdődik, majd a rendezésiek, keresések, gráfalgoritmusok után olyan bonyolultabb algoritmusok párhuzamosításáról is szó esik, mint a titkosítási, tömörítési és a geometriai problémákat megoldó algoritmusok. Minden esetben az algoritmus bemutatás után foglalkozunk a párhuzamosítás lehetőségével, valamint a soros és párhuzamos implementációval C# nyelven.

    Mindezek mellett a tananyagban megtalálható egy rövid fejezet, amely a fontosabb adatszerkezetek elosztott használatával foglalkozik, amely azért fontos, mert a párhuzamos algoritmusok gyakran használhatnak ilyen adatszerkezeteket, amelyeket ilyenkor speciálisan kell kezelnünk (például a kölcsönös kizárás megvalósításával).

    3

  • Tartalomjegyzék • Bevezető • Programozási tételek • Keresések • Mintaillesztések • Rendezések (1) • Rendezések (2) • Mátrixműveletek • Gráfalgoritmusok (1) • Gráfalgoritmusok (2) • Geometria • Tömörítés • Titkosítás

    www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK 4

  • 1. óra Bevezető

    Algoritmus fogalma, tulajdonságai Algoritmusok elemzése Aszimptotikus jelölések Példák Algoritmusok párhuzamosítása Módszerek Példák Programok Irodalomjegyzék

    © Kurdi Zsombor, ÓE NIK www.tankonyvtar.hu 5

    PresenterPresentation NotesA tartalomjegyzékben felsorolt témák nagy részének ismeretét feltételezhetjük a hallgatókról,mert azokat korábbi órákon már tanulták. Ennek az órának a célja az ismeretek felelevenítése,illetve az esetleges hiányosságok pótlása (amennyiben hiányosság mutatkozik valamely hallgatóelőismereteiben, az órán elhangzottakon kívül tanórán kívüli utánajárás is szükséges lehet).

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Hallgatói tájékoztató A jelen bemutatóban található adatok, tudnivalók és információk a

    számonkérendő anyag vázlatát képezik. Ismeretük szükséges, de nem elégséges feltétele a sikeres zárthelyinek, illetve vizsgának.

    Sikeres zárthelyihez, illetve vizsgához a jelen bemutató tartalmán felül a kötelező irodalomként megjelölt anyag, a gyakorlatokon szóban, illetve a táblán átadott tudnivalók ismerete, valamint a gyakorlatokon megoldott példák és az otthoni feldolgozás céljából kiadott feladatok önálló megoldásának képessége is szükséges.

    6

  • Algoritmus fogalma, tulajdonságai

    www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK 7

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Algoritmus • Algoritmuson olyan módszert (utasítások sorozatát) értünk, amely

    valamely problémára megoldást ad. • A fogalom a matematikában jelent meg, de az informatika

    népszerűvé válása ültette át a köznyelvbe. • Algoritmust lehet adni

    – egy bútordarab összeszerelésére, – egy étel elkészítésére, – otthonunkból az iskolába való eljutásra, – két szám legnagyobb közös osztójának kiszámítására. – …

    8

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Algoritmus definíciója • Turing: egy probléma megoldására adott utasítássorozat akkor

    tekinthető algoritmusnak, ha van egy vele ekvivalens Turing-gép, amely minden megoldható bemenetre megáll.

    • Alternatív definíciók – Regisztergép – Lambda-kalkulus – Rekurzív függvények – Chomsky-nyelvtanok – Markov-algoritmusok

    • Mindegyik definíció ekvivalens a Turing-féle meghatározással.

    9

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Algoritmusok tulajdonságai • Alaptulajdonságok

    – Egy algoritmus egyértelműen leírható véges szöveggel (statikus végesség). – Egy algoritmus minden lépése ténylegesen kivitelezhető. – Egy algoritmus minden időpontban véges sok tárat használ (dinamikus

    végesség). – Egy algoritmus véges sok lépésből áll (termináltság).

    • Ezek alapján az algoritmus fogalma – Egy algoritmus ugyanarra a bemenetre mindig ugyanazt az eredményt adja

    (determináltság). – Minden időpontban egyértelműen adott a következő lépés

    (determinisztikusság).

    10

  • Algoritmusok elemzése

    www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK 11

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Algoritmusok elemzése • Befejeződés

    – Kiszámíthatóságelméleti feladat.

    • Tár- és időigény – Bonyolultságelméleti feladat. – Természetes számokon értelmezett függvények segítségével írható le. – Aszimptotikus korlátokkal adható meg. – A továbbiakban csak ezzel foglalkozunk.

    12

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Algoritmusok elemzése • Legyen két függvény f, g: N → Z

    – Ha ∃c > 0 és n0, hogy ha n > n0, akkor 0 ≤ f(n) ≤ c⋅g(n), akkor a g függvényt f aszimptotikusan ÉLES felső korlátjának nevezzük (Jele: f(n) = O(g(n) vagy f = O(g))

    – Ha ∃c > 0 és n0, hogy ha n > n0, akkor 0 ≤ f(n) < c⋅g(n), akkor a g függvényt f aszimptotikusan NEM ÉLES felső korlátjának nevezzük (Jele: f(n) = o(g(n) vagy f = o(g))

    – Ha ∃c > 0 és n0, hogy ha n > n0, akkor 0 ≤ c⋅g(n) ≤ f(n), akkor a g függvényt f aszimptotikusan ÉLES alsó korlátjának nevezzük (Jele: f(n) = Ω(g(n) vagy f = Ω(g))

    – Ha ∃c > 0 és n0, hogy ha n > n0, akkor 0 ≤ c⋅g(n) < f(n), akkor a g függvényt f aszimptotikusan NEM ÉLES alsó korlátjának nevezzük (Jele: f(n) = ω(g(n) vagy f = ω(g))

    – Ha ∃c1,c2 > 0 és n0, hogy ha n > n0, akkor 0 ≤ c1⋅g(n) ≤ f(n) ≤ c2⋅g(n), akkor a g függvényt f aszimptotikusan éles korlátjának nevezzük (Jele: f(n) = Θ(g(n) vagy f = Θ(g))

    13

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Algoritmusok elemzése

    14

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Algoritmusok elemzése • A definíciók alapján triviális állítás

    – ∀f,g : N → Z függvényre f(n) = Θ(g(n)) ↔ f(n) = O(g(n)) és f(n) = Ω(g(n))

    Azaz egy függvény pontosan akkor aszimptotikusan éles korlátja

    egy másik függvénynek, ha aszimptotikusan éles alsó és aszimptotikusan éles felső korlátja a függvénynek.

    15

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Algoritmusok elemzése • Az O, o, Ω, ω és Θ jelölések mint bináris relációk tulajdonságai

    – O, o, Ω, ω és Θ tranzitívak (pl.: f = ω(g) ∧ g = ω(h) → f = ω(h)) – O, Ω és Θ reflexívek (pl. f = Θ(f)) – Θ szimmetrikus (f = Θ(g) ↔ g = Θ(f)) – O és Ω, valamint o és ω „felcserélten szimmetrikusak” (pl.: f = O(g) ↔ g =

    Ω(f)) – Rögzített h függvény mellett O(h), o(h), Ω(h), ω(h) és Θ(h) halmazok zártak az

    összeadásra és a pozitív számmal való szorzásra (pl.: f = ω(h) ∧ g = ω(h) → f + g = ω(h)) és (pl.: f = ω(h) ∧ c > 0 → c⋅f = ω(h))

    – Összegben a nagyobb függvény határozza meg az aszimptotikát: f + g = Θ(max(f, g)) (A max ebben az esetben az aszimptotikusan nagyobb függvényt jelenti.)

    16

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Algoritmusok elemzése • Az O, o, Ω, ω és Θ jelölések mint bináris relációk tulajdonságai

    (folytatás) – Polinom esetén a legnagyobb fokú tag a meghatározó: aknk + ak-1nk-1 + … + a1n

    + a0 = Θ(n k) – Bármely két (1-nél nagyobb alapszámú) logaritmikus függvény

    aszimptotikusan egyenértékű: logan = Θ(logbn). Ezért az alap feltüntetése nem szükséges logan = Θ(logn)

    – Hatványfüggvények esetén különböző kitevők különböző függvényosztályokat jelölnek ki: a ≥ 0 és ε > 0 esetén na = O(na+ε) és na ≠ Θ(na+ε), tehát na = o(na+ε)

    17

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Példa (Összegzés) • Bemenet: n db érték (elemek). • Kimenet: az input értékek összege. • Algoritmus:

    s = 0 for i = 1 to n s = s + elemek[i]

    • Lépésszám – Legjobb eset: n – Legrosszabb eset: n – Átlagos eset: n – Függvényosztály: Θ(n)

    18

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Példa (Számlálás) • Bemenet: n db érték (elemek). • Kimenet: az input értékek közül adott tulajdonságú elemek

    darabszáma. • Algoritmus:

    d = 0 for i = 1 to n if χ(elemek[i]) d = d + 1

    • Lépésszám – Legjobb eset: n – Legrosszabb eset: n – Átlagos eset: n – Függvényosztály: Θ(n)

    19

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Példa (Maximumkeresés) • Bemenet: n db érték (elemek). • Kimenet: az input értékek közül a maximális elem. • Algoritmus:

    max = elemek[1] for i = 2 to n if elemek[i] > max max = elemek[i]

    • Lépésszám – Legjobb eset: n – Legrosszabb eset: n – Átlagos eset: n – Függvényosztály: Θ(n)

    20

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Párhuzamos algoritmusok • A párhuzamos algoritmusok olyan algoritmusok, amelyek a

    feladatot több részre osztva, egymással párhuzamosan (több processzoron) egyidejűleg futnak.

    • Ezeket az algoritmusokat két nagy csoportba sorolhatjuk – Megosztott algoritmusok Az algoritmust alkotó folyamatok közös memóriát használnak, és azon

    keresztül kommunikálnak egymással. – Elosztott algoritmusok Az algoritmushoz tartozó folyamatok teljesen szeparált tárterületen

    dolgoznak, majd valamilyen módszerrel összegzik az eredményeket.

    21

  • Algoritmusok párhuzamosítása

    www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK 22

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Algoritmusok párhuzamosítása • „Oszd meg és uralkodj” elv segítségével

    – Az adatok felosztása a processzorok (szálak v. folyamatok) között, majd az eredmények összefésülése

    Ebben az esetben valamennyi szál elvégzi a teljes algoritmust és az általuk szolgáltatott eredményeket kell valamelyik szálnak összefésülni (ez történhet új algoritmussal vagy a párhuzamosított algoritmus újbóli végrehajtásával).

    Olyan algoritmusok esetén hatékony megoldás, amelyek valamennyi inputadatot megvizsgálnak a futás során. (pl. összegzés).

    – A feladatok felosztása a processzorok (szálak v. folyamatok) között Ebben az esetben a szálak az algoritmusnak csak egy részét végzik el és az

    általuk számolt részeredményt a következő szálnak adják (futószalagszerű rendszer). Az algoritmus végeredményét az utolsó szál szolgáltatja.

    Olyan algoritmusok esetén hatékony megoldás, amelyek felbonthatók elemi lépések sorozatára, amelyeket az inputadatokon kell elvégezni, hogy megkapjuk az outputot. (Pl. sin számítás.)

    23

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Adatmegosztás

    24

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Feladatmegosztás

    25

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Példa (Összegzés) • Párhuzamosítás adatmegosztással

    – Osszuk k részre az n értéket. – Összegezzük a részeket párhuzamosan. – Összegezzük az egyes részek eredményeit.

    • Lépésszám – Legjobb eset: n / k + k – Legrosszabb eset: n / k + k – Átlagos eset: n / k + k – Függvényosztály: Θ(n / k + k)

    26

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Példa (Számlálás) • Párhuzamosítás adatmegosztással

    – Osszuk k részre az n értéket. – Végezzük el a számlálást a részeken párhuzamosan. – Összegezzük az egyes részek eredményeit.

    • Lépésszám – Legjobb eset: n / k + k – Legrosszabb eset: n / k + k – Átlagos eset: n / k + k – Függvényosztály: Θ(n / k + k)

    27

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Példa (Maximumkeresés) • Párhuzamosítás adatmegosztással

    – Osszuk k részre az n értéket. – Keressük meg a részek maximumait párhuzamosan. – Keressük meg a maximumot a részeredmények között.

    • Lépésszám – Legjobb eset: n / k + k – Legrosszabb eset: n / k + k – Átlagos eset: n / k + k – Függvényosztály: Θ(n / k + k)

    28

  • Programok

    www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK 29

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Példaprogramok • A tananyag további részében szereplő példaprogramok

    inputadatait a szamok.txt fájl tartalmazza – A fájl első sora a benne található inputadatok darabszámát tartalmazza. – Minden további sor egy-egy inputadatot tartalmaz.

    30

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Adatbeolvasás private const string inputFile = "szamok.txt"; private static int[] Beolvas() { StreamReader input = new StreamReader(inputFile); int méret = Convert.ToInt32(input.ReadLine()); int[] számok = new int[méret]; for (int i = 0; i < számok.Length; ++i) számok[i] = Convert.ToInt32(input.ReadLine()); input.Close(); return számok; }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    31

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Példaprogramok • Minden példaprogram elején az inputfájl tartalmát beolvassuk

    egy tömbbe. • Ehhez az input fájl nevét egy konstansban tároljuk. • A beolvasást a Beolvas() nevű művelet végzi. • Az algoritmus futási idejét Stopwatch objektum segítségével

    mérjük. • A program végén az eredményt és a futási időt megjelenítjük a

    képernyőn.

    32

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Program (Soros) private static Stopwatch stopper = new Stopwatch(); static void Main(string[] args) { int[] számok = Beolvas(); stopper.Start(); // algoritmus stopper.Stop(); // eredmény és futási idő kiírás }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    33

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Példa (Összegzés) // algoritmus int s = 0; for (int i = 0; i < számok.Length; ++i) s += számok[i]; // eredmény és futási idő kiírás Console.WriteLine("A számok összege: {0}", s); Console.WriteLine("Összesen {0} db számot adtam össze.", számok.Length); Console.WriteLine("Futási idő: {0}", stopper.Elapsed);

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    34

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Példa (Számlálás) // algoritmus int d = 0; for (int i = 0; i < számok.Length; ++i) if (Feltétel(számok[i]) ++d; // eredmény és futási idő kiírás Console.WriteLine("A feltételt teljesítő elemek darabszáma: {0}", d); Console.WriteLine("Összesen {0} db elemet vizsgáltam.", számok.Length); Console.WriteLine("Futási idő: {0}", stopper.Elapsed); // a Feltétel tetszőleges logikai értékű függvény lehet // most a páros számokat számláljuk private bool Feltétel(int n) { return n % 2 == 0; }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    35

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Példa (Maximumkeresés) // algoritmus int max = számok[0]; for (int i = 1; i < számok.Length; ++i) if (számok[i] > max) max = számok[i]; // eredmény és futási idő kiírás Console.WriteLine("A legnagyobb szám: {0}", max); Console.WriteLine("Összesen {0} db számot vizsgáltam.", számok.Length); Console.WriteLine("Futási idő: {0}", stopper.Elapsed);

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    36

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Program (Párhuzamos) private struct SzálParaméter { public int SzálIndex; public int[] Számok; public int StartIndex; public int Hossz; } private static Stopwatch stopper = new Stopwatch(); private static object sync = new object(); private static int[] eredmények = new int[](); private static int lefutottSzálak = 0; static void Main(string[] args) { int[] számok = Beolvas(); stopper.Start(); for (int i = 0; i < szálakSzáma; ++i) { SzálParaméter paraméter; paraméter.SzálIndex = i; Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    37

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Program (Párhuzamos) paraméter.SzálIndex = i; paraméter.Számok = számok; paraméter.Hossz = számok.Length / szálakSzáma; paraméter.StartIndex = paraméter.Hossz * i; ThreadPool.QueueUserWorkItem(new WaitCallback(Szálfüggvény), paraméter); } while (lefutottSzálak < szálakSzáma) Thread.Sleep(1); // összefésülés stopper.Stop(); // eredmény és futási idő kiírás } private static void Szálfüggvény(object obj) { SzálParaméter param = (SzálParaméter)obj; // soros algoritmus

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    38

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Program (Párhuzamos) eredmények[param.SzálIndex] = /* az algoritmus eredménye */ lock (sync) { ++lefutottSzálak; } }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    39

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Példa (Összegzés) // összefésülés int s = 0; for (int i = 0; i < eredmények.Length; ++i) s += eredmények[i]; // eredmény és futási idő kiírás Console.WriteLine("A számok összege: {0}", s); Console.WriteLine("Összesen {0} db számot adtam össze.", számok.Length); Console.WriteLine("Futási idő: {0}", stopper.Elapsed);

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    40

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Példa (Számlálás) // összefésülés int d = 0; for (int i = 0; i < eredmények.Length; ++i) d += eredmények[i]; // eredmény és futási idő kiírás Console.WriteLine("A feltételt teljesítő elemek darabszáma: {0}", d); Console.WriteLine("Összesen {0} db elemet vizsgáltam.", számok.Length); Console.WriteLine("Futási idő: {0}", stopper.Elapsed); // a Feltétel tetszőleges logikai értékű függvény lehet // most a páros számokat számláljuk private bool Feltétel(int n) { return n % 2 == 0; }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    41

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Példa (Maximumkeresés) // összefésülés int max = eredmények[0]; for (int i = 1; i < eredmények.Length; ++i) if (eredmények[i] > max) max = eredmények [i]; // eredmény és futási idő kiírás Console.WriteLine("A legnagyobb szám: {0}", max); Console.WriteLine("Összesen {0} db számot vizsgáltam.", számok.Length); Console.WriteLine("Futási idő: {0}", stopper.Elapsed);

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    42

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Házi feladat Próbálja ki a példaprogramokat! Kíséreljen meg javítani a

    párhuzamos változatok hatékonyságán!

    Megjegyzés – Lehetőség szerint a programokat futtassa egy-, illetve többprocesszoros

    gépeken!

    43

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Irodalomjegyzék • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein: Új algoritmusok,

    Scolar Kiadó, 2003.

    44

  • www.tankonyvtar.hu

    2. óra Programozási tételek

    Programozási tételek Összegzés Számlálás Maximumkeresés Másolás Kiválogatás Szétválogatás Metszet Unió Irodalomjegyzék

    © Kurdi Zsombor, ÓE NIK 45

    PresenterPresentation NotesValamennyi a tartalomjegyzékben felsorolt algoritmus ismeretét feltételezhetjük a hallgatókról,mert azokat korábbi órákon már tanulták, sőt azok implementációját is nagy valószínűséggelelkészítették valamely programozási nyelven. Ennek az órának a célja az ismeretek felelevenítése,illetve az esetleges hiányosságok pótlása (amennyiben hiányosság mutatkozik valamely hallgatóelőismereteiben, az órán elhangzottakon kívül tanórán kívüli utánajárás is szükséges lehet).

  • www.tankonyvtar.hu

    Programozási tételek

    © Kurdi Zsombor, ÓE NIK 46

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Programozási tételek • Egy adott feladatosztályba tartozó összes feladatra általános

    megoldást adnak. • Csoportosításuk

    – Egy sorozathoz egy értéket rendelő feladatok. • Pl.: számítsuk ki n db szám összegét.

    – Egy sorozathoz egy sorozatot rendelő feladatok. • Pl.: másoljuk egy sorozat elemeit fordított sorrendben egy másik sorozatba.

    – Sorozathoz több sorozatot rendelő feladatok. • Pl.: válogassuk szét egy sorozat páros és páratlan elemeit.

    – Több sorozathoz egy sorozatot rendelő feladatok. • Pl.: számítsuk ki két sorozat közös elemeit (metszetét).

    47

  • www.tankonyvtar.hu

    Összegzés

    © Kurdi Zsombor, ÓE NIK 48

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Összegzés • Feladat

    – Számítsuk ki n db szám összegét.

    • Sorozathoz értéket rendel.

    • Lásd: előző óra.

    49

  • www.tankonyvtar.hu

    Számlálás

    © Kurdi Zsombor, ÓE NIK 50

  • Számlálás • Feladat

    – Számláljuk meg n db számból hány telesíti F feltételt.

    • Sorozathoz értéket rendel. • F feltétel tetszőleges logikai értékű függvény lehet.

    • Lásd: előző óra.

    www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK 51

  • www.tankonyvtar.hu

    Maximumkeresés

    © Kurdi Zsombor, ÓE NIK 52

  • Maximumkeresés • Feladat

    – Keressük meg n db szám közül a legnagyobbat.

    • Sorozathoz értéket rendel. • A minimumkeresés is hasonlóan végezhető el. • Megkereshető a sorozat első, illetve utolsó maximuma (ha több

    maximum is van). • Feltétellel bővíthető, hogy a sorozat bizonyos (feltételt teljesítő)

    elemei közül keressük a maximumot = feltételes maximum keresés.

    • Lásd: előző óra.

    www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK 53

  • www.tankonyvtar.hu

    Másolás

    © Kurdi Zsombor, ÓE NIK 54

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Másolás • Feladat

    – Másoljuk át egy sorozat (s) elemeit egy másik sorozatba (t).

    • Sorozathoz sorozatot rendel.

    • Algoritmus:

    for i = 1 to n t[i] = s[i]

    55

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Másolás • A másolás közben műveletet is végezhetünk az elemeken.

    – Egyszerű művelet (pl. gyökvonás). – Összetett művelet (pl. s[i]-edik Fibonacci-szám kiszámítása).

    • Lépésszám

    – Legjobb eset: n – Legrosszabb eset: n – Átlagos eset: n – Függvényosztály: Θ(n)

    56

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Feladat Adott egy n számot tartalmazó tömb. Számolja ki a számok

    négyzetét egy új tömbbe/listába! Oldja meg a feladatot soros és párhuzamos algoritmussal is!

    57

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Megoldás (Soros) // a másolat int másolat = new int[számok.Length]; // másolás for (int i = 0; i < számok.Length; ++i) másolat[i] = számok[i] * számok[i]; // eredmény és futási idő kiírás for (int i = 0; i < számok.Length; ++i) Console.WriteLine("{0}^2 = {1}", számok[i], másolat[i]); Console.WriteLine("Összesen {0} db szám négyzetét számoltam ki.", számok.Length); Console.WriteLine("Futási idő: {0}", stopper.Elapsed);

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    58

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Megoldás (Párhuzamos) // a szál-paraméterek szerkezete struct SzálParaméter { public int[] Számok; // a beolvasott számok public int SzálIndex; // most nincs jelentősége public int StartIndex; // ahonnan elkezdi a szál olvasni a Számok tömböt public int Hossz; // ahány elemet a szálnak fel kell dolgozni } // szálfüggvény private static void Szálfüggvény(object obj) { SzálParaméter param = (SzálParaméter )obj; for (int i = param.StartIndex; i < param.StartIndex + param.Hossz; ++i) Eredmény[i] = param.Számok[i] * param.Számok[i]; // a másolás az Eredmény tömbbe // szinkronizációra nincs szükség, mert a szálak a tömb diszjunkt részeit módosítják lock (sync) // a terminálás jelzésére a lefutottSzálak változót használjuk { // itt szükséges a szinkronizáció, mert minden szál módosítja ezt a

    változót ++lefutottSzálak; }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    59

  • www.tankonyvtar.hu

    Kiválogatás

    © Kurdi Zsombor, ÓE NIK 60

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Kiválogatás • Feladat

    – Válogassuk ki egy sorozat elemeit, amelyek teljesítik az F feltételt.

    • Sorozathoz sorozatot rendel.

    • Algoritmus: j = 0 for i = 1 to n if F(s[i]) t[j] = s[i] j = j + 1

    61

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Kiválogatás • F feltétel tetszőleges logikai értékű függvény lehet.

    • Lépésszám

    – Legjobb eset: n – Legrosszabb eset: n – Átlagos eset: n – Függvényosztály: Θ(n)

    62

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Feladat Adott egy n számot tartalmazó tömb. Számolja ki a számok

    négyzetét egy új tömbbe/listába! Oldja meg a feladatot soros és párhuzamos algoritmussal is!

    63

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Megoldás (Soros) // az eredmény List négyzetszámok = new List(); // kiválogatás for (int i = 0; i < számok.Length; ++i) if (Feltétel(számok[i]) négyzetszámok.Add(számok[i]); // eredmény és futási idő kiírás Console.WriteLine("Négyzetszámok:"); for (int i = 0; i < négyzetszámok.Length; ++i) Console.WriteLine(négyzetszámok[i]); Console.WriteLine("Összesen {0} db számot vizsgáltam.", számok.Length); Console.WriteLine("Futási idő: {0}", stopper.Elapsed); // a feltétel private static bool Feltétel(int n) { return Math.Round(Math.Sqrt(n)) * Math.Round(Math.Sqrt(n)) == n; } Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    64

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Megoldás (Párhuzamos) // a szál-paraméterek szerkezete struct SzálParaméter { public int[] Számok; // a beolvasott számok public int SzálIndex; // most nincs jelentősége public int StartIndex; // ahonnan elkezdi a szál olvasni a Számok tömböt public int Hossz; // ahány elemet a szálnak fel kell dolgozni } // szálfüggvény private static void Szálfüggvény(object obj) { SzálParaméter param = (SzálParaméter )obj; for (int i = param.StartIndex; i < param.StartIndex + param.Hossz; ++i) if (Feltétel(param.Számok[i])) // most szükséges a szinkronizáció, mert az Eredmény lock (Eredmény) // lista kezelése nem diszjunkt részekben

    történik Eredmény.Add(param.Számok[i]); lock (sync) // a terminálás jelzésére a lefutottSzálak változót használjuk ++lefutottSzálak; // itt szükséges a szinkronizáció, mert minden szál módosítja ezt a

    // változót

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    65

  • www.tankonyvtar.hu

    Szétválogatás

    © Kurdi Zsombor, ÓE NIK 66

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Szétválogatás • Feladat

    – Válogassuk szét egy sorozat F feltételt teljesítő és nem teljesítő elemeit egy-egy sorozatba.

    • Sorozathoz több sorozatot rendel.

    • Algoritmus:

    j1 = 0, j2 = 0 for i = 1 to n if F(s[i]) t1[j1] = s[i] j1 = j1 + 1 else t2[j2] = s[i] j2 = j2 + 1

    67

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Szétválogatás • F feltétel tetszőleges logikai értékű függvény lehet.

    • Lépésszám

    – Legjobb eset: n – Legrosszabb eset: n – Átlagos eset: n – Függvényosztály: Θ(n)

    68

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Feladat Adott egy n számot tartalmazó tömb. Válogassuk szét a páros és

    páratlan elemeket két új tömbbe/listába! Oldja meg a feladatot soros és párhuzamos algoritmussal is!

    69

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Megoldás (Soros) // az eredmény List páros = new List(); List páratlan = new List(); // szétválogatás for (int i = 0; i < számok.Length; ++i) if (Feltétel(számok[i]) páros.Add(számok[i]); else páratlan.Add(számok[i]); // eredmény és futási idő kiírás Console.WriteLine("Páros számok:"); for (int i = 0; i < páros.Length; ++i) Console.WriteLine(páros[i]); Console.WriteLine("Páratlan számok:"); for (int i = 0; i < páratlan.Length; ++i) Console.WriteLine(páratlan[i]); Console.WriteLine("Összesen {0} db számot vizsgáltam.", számok.Length); Console.WriteLine("Futási idő: {0}", stopper.Elapsed); // a feltétel private static bool Feltétel(int n) { return n % 2 == 0; } Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

    70

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Megoldás (Párhuzamos) // a szál-paraméterek szerkezete struct SzálParaméter { public int[] Számok; // a beolvasott számok public int SzálIndex; // most nincs jelentősége public int StartIndex; // ahonnan elkezdi a szál olvasni a Számok tömböt public int Hossz; // ahány elemet a szálnak fel kell dolgozni } // szálfüggvény private static void Szálfüggvény(object obj) { SzálParaméter param = (SzálParaméter)obj; for (int i = param.StartIndex; i < param.StartIndex + param.Hossz; ++i) if (Feltétel(param.Számok[i])) // most szükséges a szinkronizáció, mert az Eredmény lock (Páros) // lista kezelése nem diszjunkt részekben történik Páros.Add(param.Számok[i]); else lock (Páratlan) Páratlan.Add(param.Számok[i]); lock (sync) // a terminálás jelzésére a lefutottSzálak változót használjuk ++lefutottSzálak; // itt szükséges a szinkronizáció, mert minden szál módosítja ezt a

    // változót } Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

    71

  • www.tankonyvtar.hu

    Metszet

    © Kurdi Zsombor, ÓE NIK 72

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Metszet • Feladat

    – Másoljuk át két (vagy több) sorozat közös elemeit egy új sorozatba.

    • Több sorozathoz egy sorozatot rendel.

    • Algoritmus

    for s in H1 if s not in H2 M = M U {s}

    73

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Metszet • A másolás közben tetszőleges műveletet elvégezhetünk az

    elemeken.

    • Lépésszám – Legjobb eset: min{n,m} – Legrosszabb eset: n*m – Átlagos eset: ~n*m – Függvényosztály: Θ(n*m)

    74

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Feladat Adott egy n és egy m számot tartalmazó tömb. Másolja át a két

    tömb közös elemeit egy új tömbbe/listába! Oldja meg a feladatot soros és párhuzamos algoritmussal is!

    75

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Megoldás (Soros) // az eredmény List metszet = new List(); // metszet for (int i = 0; i < számok1.Length; ++i) { bool tartalmaz = false; for (int j = 0; j < számok2.Length && !tartalmaz; ++j) tartalmaz = számok1[i] == számok2[j]; if (tartalmaz) metszet.Add(számok1[i]); } // eredmény és futási idő kiírás Console.WriteLine("Metszet:"); for (int i = 0; i < metszet.Length; ++i) Console.WriteLine(metszet[i]); Console.WriteLine("Az 1. sorozat elemszáma: {0}", számok1.Length); Console.WriteLine("A 2. sorozat elemszáma: {0}", számok2.Length); Console.WriteLine("Futási idő: {0}", stopper.Elapsed);

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    76

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Megoldás (Párhuzamos) // a szál-paraméterek szerkezete struct SzálParaméter { public int[] Számok1; // az egyik számsorozat public int[] Számok2; // a másik számsorozat public int SzálIndex; // most nincs jelentősége public int StartIndex; // ahonnan elkezdi a szál olvasni a Számok tömböt public int Hossz; // ahány elemet a szálnak fel kell dolgozni } // szálfüggvény private static void Szálfüggvény(object obj) { SzálParaméter param = (SzálParaméter)obj; for (int i = param.StartIndex; i < param.StartIndex + param.Hossz; ++i) { bool tartalmaz = false; for (int j = 0; j < param.Számok2.Length && !tartalmaz; ++j) tartalmaz = param.Számok1[i] == param.Számok2[j]; if (tartalmaz) // most szükséges a szinkronizáció, mert az Eredmény lock (Eredmény) // lista kezelése nem diszjunkt részekben történik Eredmény.Add(param.Számok1[i]); } lock (sync) // a terminálás jelzésére a lefutottSzálak változót használjuk ++lefutottSzálak; // itt szükséges a szinkronizáció, mert minden szál módosítja ezt a változót }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

    77

  • www.tankonyvtar.hu

    Unió

    © Kurdi Zsombor, ÓE NIK 78

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Unió • Feladat

    – Másoljuk át két (vagy több) sorozat elemeit egy új sorozatba úgy, hogy a közös elemek csak egyszer szerepeljenek.

    • Több sorozathoz egy sorozatot rendel.

    • Algoritmus

    E = H1 for s in H2 if s not in E E = E U {s}

    79

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Unió • A másolás közben tetszőleges műveletet elvégezhetünk az

    elemeken.

    • Lépésszám – Legjobb eset: ~n+m – Legrosszabb eset: n*m – Átlagos eset: n*m – Függvényosztály: Θ(n*m)

    80

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Feladat Adott egy n és egy m számot tartalmazó tömb. Másolja át a két

    tömb elemeit egy új tömbbe/listába úgy, hogy a közös elemek csak egyszer szerepeljenek! Oldja meg a feladatot soros és párhuzamos algoritmussal is!

    81

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Megoldás (Soros) // az eredmény List unió = new List(); // unió for (int i = 0; i < számok1.Length; ++i) unió.Add(számok1[i]); for (int i = 0; i < számok2.Length; ++i) { bool tartalmaz = false; for (int j = 0; j < számok1.Length && !tartalmaz; ++j) tartalmaz = számok2[i] == számok1[j]; if (!tartalmaz) unió.Add(számok2[i]); } // eredmény és futási idő kiírás Console.WriteLine("Unió:"); for (int i = 0; i < metszet.Length; ++i) Console.WriteLine(metszet[i]); Console.WriteLine("Az 1. sorozat elemszáma: {0}", számok1.Length); Console.WriteLine("A 2. sorozat elemszáma: {0}", számok2.Length); Console.WriteLine("Futási idő: {0}", stopper.Elapsed);

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

    82

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Megoldás (Párhuzamos) // a szál-paraméterek szerkezete struct SzálParaméter { public int[] Számok1; // az egyik számsorozat public int[] Számok2; // a másik számsorozat public int SzálIndex; // most nincs jelentősége public int StartIndex; // ahonnan elkezdi a szál olvasni a Számok tömböt public int Hossz; // ahány elemet a szálnak fel kell dolgozni } // szálfüggvény (a Számok2 tömb elemeit a fő szálban másoljuk az Eredménybe) private static void Szálfüggvény(object obj) { SzálParaméter param = (SzálParaméter)obj; for (int i = param.StartIndex; i < param.StartIndex + param.Hossz; ++i) { bool tartalmaz = false; for (int j = 0; j < param.Számok1.Length && !tartalmaz; ++j) tartalmaz = param.Számok2[i] == param.Számok1[j]; if (!tartalmaz) // most szükséges a szinkronizáció, mert az Eredmény lock (Eredmény) // lista kezelése nem diszjunkt részekben történik Eredmény.Add(param.Számok1[i]); } lock (sync) // a terminálás jelzésére a lefutottSzálak változót használjuk ++lefutottSzálak; // itt szükséges a szinkronizáció, mert minden szál módosítja ezt a változót }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

    83

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Házi feladat Próbálja ki a példaprogramokat! Kíséreljen meg javítani a

    párhuzamos változatok hatékonyságán!

    Megjegyzés – Lehetőség szerint a programokat futtassa egy-, illetve többprocesszoros

    gépeken!

    84

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Irodalomjegyzék • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein: Új algoritmusok, Scolar

    Kiadó, 2003.

    85

  • www.tankonyvtar.hu

    3. óra Keresések

    Keresések Lineáris keresés Bináris keresés Visszalépéses keresés Irodalomjegyzék

    © Kurdi Zsombor, ÓE NIK 86

    PresenterPresentation NotesValamennyi a tartalomjegyzékben fersorolt algoritmus ismeretét feltételezhetjük a hallgatókról,mert azokat korábbi órákon már tanulták, sőt azok implementációját is nagy valószínűséggelelkészítették valamely programozási nyelven. Ennek az órának a célja az ismeretek felelevenítése,illetve az esetleges hiányosságok pótlása (amennyiben hiányosság mutatkozik valamely hallgatóelősimereteiben, az órán elhangzottakon kívül tanórán kívüli utánajárás is szükséges lehet).

  • www.tankonyvtar.hu

    Keresések

    © Kurdi Zsombor, ÓE NIK 87

  • www.tankonyvtar.hu

    Lineáris keresés

    © Kurdi Zsombor, ÓE NIK 88

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Lineáris keresés • Feladat

    – Keressük meg egy sorozat első F feltételt teljesítő elemét (vagy annak indexét).

    • Sorozathoz értéket rendel.

    • Algoritmus for i = 1 to n if (F(s[i])) break

    89

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Lineáris keresés • F feltétel tetszőleges logikai értékű függvény lehet.

    • Lépésszám

    – Legjobb eset: 1 – Legrosszabb eset: n – Átlagos eset: n/2 – Függvényosztály: Θ(n)

    90

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Feladat Adott egy n számot tartalmazó tömb. Keresse meg az első 2-vel, 3-

    mal, 5-tel és 7-tel is osztható számot! Oldja meg a feladatot soros és párhuzamos algoritmussal is!

    91

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Megoldás (Soros) // keresés bool találat = false; int szám = 0; for (int i = 0; i < számok.Length && !találat; ++i) { if (Feltétel(számok[i])) { találat = true; szám = számok[i]; } } // eredmény és futási idő kiírás if (találat) Console.WriteLine("A feltételnek megfelelő szám: {0}", szám); else Console.WriteLine("Nincs a feltételnek megfelelő szám."); Console.WriteLine("Összesen {0} db számot vizsgáltam.", számok.Length); Console.WriteLine("Futási idő: {0}", stopper.Elapsed); // feltétel private static bool Feltétel(int n) { return n % 2 == 0 && n % 3 == 0 && n % 5 == 0 && n % 7 == 0; }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

    92

  • Lineáris keresés párhuzamosítása • Az eredmények tömbben a szálak futási állapotát is tároljuk. Ha

    egy érték. – –2 : még fut a szál. – – 1 : a szál lefutott, de nem talált a feltételnek megfelelő elemet. – Más érték: a szál lefutott és az érték a feltételnek megfelelő elem.

    • A program akkor ér véget, amint a legkisebb indexű szál talált

    eredményt (vagy egyik szál sem talált megfelelő elemet).

    www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK 93

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Megoldás (Párhuzamos) // inicializálás for (int i = 0; i < szálakSzáma; ++i) eredmények[i] = -2; … // lefutás ellenőrzés int index = 0; while (index < szálakSzáma && eredmények[index] < 0) { if (eredmények[index] == -1) ++index; Thread.Sleep(1); }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    94

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Megoldás (Párhuzamos) // a szál-paraméterek szerkezete struct SzálParaméter { public int[] Számok; // a beolvasott számok public int SzálIndex; // az eredmény tömbben erre az indexre írja a szál a futás eredményét public int StartIndex; // ahonnan elkezdi a szál olvasni a Számok tömböt public int Hossz; // ahány elemet a szálnak fel kell dolgozni } // szálfüggvény private static void Szálfüggvény(object obj) { SzálParaméter param = (SzálParaméter)obj; bool találat = false; int szám = 0; for (int i = param.StartIndex; i < param.StartIndex + param.Hossz; ++i) { if (Feltétel(param.Számok[i])) { találat = true; szám = param.Számok[i]; } } if (találat) // szinkronizációra nincs szükség, mert a szálak az eredmény tömb különböző részét módosítják eredmények[param.SzálIndex] = szám; else eredmények[param.SzálIndex] = -1; } Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

    95

  • www.tankonyvtar.hu

    Bináris keresés

    © Kurdi Zsombor, ÓE NIK 96

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Bináris keresés • Feladat

    – Döntsük el, hogy egy rendezett sorozat tartalmazza-e az E elemet.

    • Sorozathoz értéket rendel.

    • Algoritmus

    a = 1, f = n, találat = false while a E) f = k – 1 else a = k + 1

    97

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Bináris keresés • Lépésszám

    – Legjobb eset: 1 – Legrosszabb eset: log2n – Átlagos eset: ~log2n – Függvényosztály: Θ(log2n)

    98

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Feladat Adott egy n számot tartalmazó rendezett tömb. Döntse el, hogy

    tartalmazza-e a tömb a 384-es számot! Oldja meg a feladatot soros és párhuzamos algoritmussal is!

    99

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Megoldás (Soros) // keresés int eleje = 0; int vége = számok.Length; while (eleje < vége) { int közepe = (eleje + vége) / 2; if (számok[közepe] > keresettSzám) vége = közepe - 1; else if (számok[közepe] == keresettSzám) eleje = vége = közepe; else eleje = közepe + 1; } // eredmény és futási idő kiírás if (eleje == vége) Console.WriteLine("A tömb a(z) {0}. indexen tartalmazza a(z) {1} számot.", eleje, keresettSzám); else Console.WriteLine("A tömb nem tartalmazza a(z) {0} számot.", keresettSzám); Console.WriteLine("Összesen {0} db számot vizsgáltam.", számok.Length); Console.WriteLine("Futási idő: {0}", stopper.Elapsed);

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    100

  • Bináris keresés párhuzamosítása • Az eredmények tömb helyett eleje és vége nevű tömbök

    tartalmazzák az egyes részeken végzett bináris keresések indexeit. • A korábbi adatfelosztás helyett új módszert alkalmazunk.

    • A program akkor ér véget, amint egy szál megtalálta a keresett elemet, vagy minden szál lefutott.

    • Emiatt a keresés eredménye nemdeterminisztikus (de az eldöntéshez nem szükséges determinisztikus eredmény).

    www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK 101

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Adatbelovasás // az adatfelosztási módszernek megfelelő beolvasás private static int[,] Beolvas() { StreamReader input = new StreamReader(inputFile); int méret = Convert.ToInt32(input.ReadLine()); int[,] számok = new int[szálakSzáma, méret / szálakSzáma]; for (int i = 0; i < méret; ++i) számok[i % szálakSzáma, i /szálakSzáma] = Convert.ToInt32(input.ReadLine()); input.Close(); return számok; }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    102

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Megoldás (Párhuzamos) // inicializálás for (int i = 0; i < szálakSzáma; ++i) { eleje[i] = 0; vége[i] = számok.GetLength(1) – 1; } … // lefutás ellenőrzés int index = -1; bool vanFutóSzál = true; while (vanFutóSzál && index < 0) { vanFutóSzál = false; for (int i = 0; i < szálakSzáma; ++i) { if (eleje[i] == vége[i]) index = eleje[i] * szálakSzáma + i; else vanFutóSzál = true; } Thread.Sleep(1); } Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

    103

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Megoldás (Párhuzamos) // a szál-paraméterek szerkezete struct SzálParaméter { public int[] Számok; // a beolvasott számok public int SzálIndex; // az eredmény tömbben erre az indexre írja a szál a futás

    eredményét public int Keresett Szám; // a keresett szám } // szálfüggvény private static void Szálfüggvény(object obj) { SzálParaméter param = (SzálParaméter )obj; while (eleje[param.SzálIndex] < vége[param.SzálIndex]) { int közepe = (eleje[param.SzálIndex] + vége[param.SzálIndex]) / 2; if (param.Számok[param.SzálIndex, közepe] > param.KeresettSzám) vége[param.SzálIndex] = közepe - 1; else if (param.Számok[param.SzálIndex, közepe] == param.KeresettSzám) eleje[param.SzálIndex] = vége[param.SzálIndex] = közepe; else eleje[param.SzálIndex] = közepe + 1; } } Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

    104

  • www.tankonyvtar.hu

    Visszalépéses keresés

    © Kurdi Zsombor, ÓE NIK 105

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Visszalépéses keresés • Feladat

    – Egy rendezett N-est (E1, E2, ... EN) keresünk, amely eleget tesz F feltételnek.

    • A rendezett N-es minden komponense rögzített értékkészletből

    származhat (pl. E1 Є {R11, R12, ... R1k}). • Az Ei komponenseket részeredményeknek nevezzük. • Az egyes értékkészletek számosságát Mi-vel jelöljük. • Az F feltétel olyan logikai értékű függvény, amely esetében

    tetszőleges részeredmény esetében megállapítható, hogy az lehet-e (vagy sem) egy jó eredmény része.

    106

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Visszalépéses keresés • Bemenet

    – N : a részeredmények száma. – Mi : a részeredmények értékkészletének számossága. – Rij : a részeredmények lehetséges értékei (értékkészlet).

    • Kimenet (egy megoldást keresünk)

    – Van-e teljes megoldás. – Az egyes részeredmények értéke a megoldásban.

    • Kimenet (minden megoldást keressük) – Az összes rendezett N-es, amely megoldás.

    107

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Feladat Adott egy sakktábla. Helyezzen fel a táblára 8 királynőt úgy, hogy

    közülük semelyik kettő se üsse egymást! Találja meg a probléma összes lehetséges megoldását! Oldja meg a feladatot soros és párhuzamos algoritmussal is!

    108

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Keresés (Soros) private static void Keresés(int[] királynők, int i, List eredmény) { for (int j = 0; j < királynőkSzáma; ++j) { if (JóÁllás(királynők, i, j)) { királynők[i] = j; if (i < királynőkSzáma – 1) Keresés(királynők, i + 1, eredmény); else eredmény.Add(ToString(királynők)); } } }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    109

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Segédfüggvény: JóÁllás private static bool JóÁllás(int[] királynők, int i, int j) { bool nincsÜtés = true; for (int k = 0; k < i && nincsÜtés; ++k) { if (királynők[k] == j) nincsÜtés = false; if (királynők[k] == j + (i – k)) nincsÜtés = false; if (királynők[k] == j – (i – k)) nincsÜtés = false; } return nincsÜtés; }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    110

  • Párhuzamosítás • A „rekurzió mentén” párhuzamosítunk: a Keresés() függvény

    rekurzív hívását külön szálon indítjuk el.

    • Minden szál saját másolattal rendelkezik a részeredményről. – Egyszerűbb szinkronizáció. – Nem szükséges az „eddig bejárt út” tárolása a visszalépéshez.

    • A szálak lefutásának ellenőrzéséhez számláljuk az elindított és a már lefutott szálakat. – Ha minden szál lefutott (azaz a két számláló azonos értéken áll), akkor kiírjuk

    az eredményt.

    • Ezzel a fajta párhuzamosítással nincs szükség visszalépésre, mert a

    visszalépés után bejárandó úton már egy másik szál dolgozik.

    www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK 111

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Keresés (Párhuzamos) private static void Szálfüggvény(object obj) { SzálParaméter param = (SzálParaméter)obj; for (int j = 0; j < KirálynőkSzáma; ++j) { if (JóÁllás(param.Királynők, param.OszlopIndex, j)) { param.Királynők[param.OszlopIndex] = j; if (param.OszlopIndex < királynőkSzáma – 1) { SzálParaméter paraméter; paraméter.Királynők = ÁllásMásol(param.Királynők); paraméter.OszlopIndex = param.OszlopIndex + 1; paraméter.Eredmény = param.Eredmény; lock (syncElindított) { ++ elindítottSzálak; } ThreadPool.QueueUserWorkItem(new WaitCallback(Szálfüggvény), paraméter); } Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    112

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Keresés (Párhuzamos) else { lock (param.Eredmény) { param.Eredmény.Add(ToString(param.Királynők)); } } } } lock (syncLefutott) { ++lefutottSzálak; } }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    113

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Házi feladat Próbálja ki a példaprogramokat! Kíséreljen meg javítani a

    párhuzamos változatok hatékonyságán! Számítsa ki a párhuzamos algoritmusok lépésszámát!

    Megjegyzések – Lehetőség szerint a programokat futtassa egy-, illetve többprocesszoros

    gépeken! – A lépésszámot a legjobb, a legrosszabb és az általános esetre is adja meg!

    114

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Irodalomjegyzék címsora • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein: Új algoritmusok, Scolar

    Kiadó, 2003.

    • Randomized Parallel Algorithms for Backtrack Search and Branch-and-Bound Computation http://rsim.cs.illinois.edu/arch/qual_papers/systems/7.pdf

    115

  • www.tankonyvtar.hu

    4. óra Mintaillesztések

    Mintaillesztések Brute-Force algoritmus Knuth–Morris–Pratt algoritmus QuickSearch algoritmus Irodalomjegyzék

    © Kurdi Zsombor, ÓE NIK 116

    PresenterPresentation NotesAz ezen az órán tárgyalt algoritmusok ismeretét nem feltételezzük a hallgatókról.

  • www.tankonyvtar.hu

    Mintaillesztések

    © Kurdi Zsombor, ÓE NIK 117

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Mintaillesztés • Feladat

    – Adott elemek egy hosszabb (szöveg) és rövidebb (minta) sorozata.

    – Döntsük el, hogy a minta megtalálható-e a szövegben, VAGY – keressük meg a minta első előfordulását a szövegben, VAGY – keressük meg a minta összes előfordulását a szövegben.

    • Leggyakoribb felhasználás: karaktersorozatok keresése hosszabb

    szövegben.

    • A példaprogramokban a szoveg.txt fájl tartalmát használjuk szövegként.

    118

    PresenterPresentation NotesA továbbiakban a mintaillesztés problémáját úgy kezeljük, mintha szövegben keresnék részeket. A példák jellege is ilyen.Természetesen általánosítással az itt bemutatott algoritmusok más típusú objektumokon végzett mintaillesztésre is használhatók.

  • www.tankonyvtar.hu

    Brute-Force algoritmus

    © Kurdi Zsombor, ÓE NIK 119

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Brute-Force algoritmus • Illesszük a mintát (k hosszú) a szöveg (n hosszú) minden indexére

    és ellenőrizzük, hogy a teljes minta illeszkedik-e ott. • Lépésszám

    – Legjobb eset: k – Legrosszabb eset: k * n – Átlagos eset: k * n / 2 – Függvényosztály: Θ(n)

    120

    PresenterPresentation NotesEz az algoritmus a triviális megoldást implementálja.

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Adatbelovasás private static string Beolvas() { StreamReader input = new StreamReader(inputFile); string szöveg = input.ReadToEnd(); input.Close(); return szöveg; }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    121

    PresenterPresentation NotesA mintaillesztő algoritmusokhoz egy hosszú szöveget tartalmazó fájlt használunk a korábbi számok.txt helyett.

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Program static void Main(string [] args) { string szöveg = Beolvas(); bool egyezik = false; int i; for (i = 0; i < szöveg.Length – keresett.Length && !egyezik; ++i) { egyezik = true; for (int j = 0; j < keresett.Length && egyezik; ++j) { egyezik = szöveg[i + j] == keresett[j]; } } // eredmények kiíratása }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    122

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Feladat Készítse el a bemutatott algoritmus párhuzamos

    implementációját! Használja a lineáris keresésnél megismert módszereket!

    123

    PresenterPresentation NotesA párhuzamos implementáció egyszerű módosíása a korábbi párhuzamos lineáris keresésnek.Ha a hallgatók nem boldogulnak az önálló megoldással, módosítsuk közösen azt a példát.(A megoldást lásd: Példaprogramok/Párhuzamos/BruteForce.zip.)

  • www.tankonyvtar.hu

    Knuth–Morris–Pratt algoritmus

    © Kurdi Zsombor, ÓE NIK 124

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Knuth–Morris–Pratt algoritmus • Alapötlet

    – Amikor az illeszkedés elromlik, akkor nem feltétlenül kell a következő helyen újrailleszteni a mintát.

    – Amennyiben a mintában találhatók ismétlődő részek, akkor nagyobb lépés is megtehető az illesztésben.

    • A prefix és szuffix szakaszok a minta ismeretében meghatározhatók.

    • Már a mintaillesztés kezdete előtt kiszámolható, hogyan kell áthelyezni a mintát, amikor az nem illeszkedik.

    125

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Mintaáthelyezések számítása private static int[] KövetkezőSzámol() { int[] következő = new int[keresett.Length]; következő[0] = 0; for (int i = 1, j = 0; i < keresett.Length;) { if (keresett[i] == keresett[j]) { következő[i] = j; ++i; ++j; } else if (j == 0) { következő[i] = 0; ++i; } else j = következő[j]; } return következő; } Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    126

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Program static void Main(string [] args) { string szöveg = Beolvas(); int[] következő = KövetkezőSzámol(); int i, j; for (i = 0, j = 0; i < szöveg.Length && j < keresett.Length;) { if (szöveg[i] == keresett[j]) { ++i; ++j; } else if (j == 0) ++j; else j = következő[j]; } // eredmények kiíratása }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    127

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Feladat Készítse el a bemutatott algoritmus párhuzamos

    implementációját! Használja a lineáris keresésnél megismert módszereket!

    128

    PresenterPresentation NotesA párhuzamos implementáció egyszerű módosíása a korábbi párhuzamos lineáris keresésnek.Ha a hallgatók nem boldogulnak az önálló megoldással, módosítsuk közösen azt a példát.(A megoldást lásd: Példaprogramok/Párhuzamos/KnuthMorrisPratt.zip.)

  • www.tankonyvtar.hu

    QuickSearch algoritmus

    © Kurdi Zsombor, ÓE NIK 129

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    QuickSearch algoritmus • Alapötlet

    – A Knuth–Morris–Pratt algoritmushoz hasonló ugrásokkal csökkentsük az illesztések számát.

    – Amennyiben a minta utáni első helyen olyan elem van, amely nincs a mintában, ez után a jel után folytathatjuk az illesztést.

    130

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Ugrások számítása private static Dictionary UgrásSzámol() { Dictionary ugrás = new Dictionary(); for (int i = 0; i < keresett.Length; ++i) { ugrás[keresett[i]] = keresett.Length – i; } return ugrás; }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    131

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Program static void Main(string [] args) { string szöveg = Beolvas(); Dictionary ugrás = UgrásSzámol(); int i, j; for (i = 0, j = 0; i < szöveg.Length – keresett.Length && j < keresett.Length;) { if (szöveg[i + j] == keresett[j]) ++j; else if (i == szöveg.Length – keresett.Length – 1) ++i; else i += ugrás.ContainsKey(szöveg[i + keresett.Length]) ? ugrás[szöveg[i + keresett.Length]] : keresett.Length + 1; } // eredmények kiíratása }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    132

  • Párhuzamosítás • Újfajta megoldás. • Daraboljuk fel a szöveget azon karakterek mentén, amelyek nem

    szerepelnek a mintában. • Az így keletkező részszövegekben elegendő illeszteni a mintát. • Ezt párhuzamosan is megtehetjük.

    • Ebben az esetben nem szükséges figyelni az átfedéseket az egyes

    részek között, mert a minta úgy nem illeszkedhet.

    • A módszer hatékonysága tovább javítható, ha csak azokat a részeket vizsgáljuk, amelyek nem rövidebbek a mintánál.

    www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK 133

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Adatbeolvasás private static string Beolvas() { StreamReader input = new StreamReader(inputFile); string szöveg = input.ReadToEnd(); input.Close(); int előző = 0; Dictionary részek = new Dictionary(); for (int i = 0; i < szöveg.Length; ++i) { if (!keresett.Contains(szöveg[i])) { if (i > előző + 1) { részek.Add(előző, szöveg.Substring(előző, i – előző)); } előző = i; } } return szöveg; }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    134

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Házi feladat Próbálja ki a példaprogramokat! Kíséreljen meg javítani a

    párhuzamos változatok hatékonyságán!

    Megjegyzés – Lehetőség szerint a programokat futtassa egy-, illetve többprocesszoros

    gépeken!

    135

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Irodalomjegyzék • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein: Új algoritmusok, Scolar

    Kiadó, 2003.

    136

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    5. óra Rendezések (1)

    Rendezések Buborékrendezés ShellSort HeapSort Irodalomjegyzék

    137

    PresenterPresentation NotesValamennyi a tartalomjegyzékben fersorolt algoritmus ismeretét feltételezhetjük a hallgatókról,mert azokat korábbi órákon már tanulták. Valószínűleg ezen algoritmusok ismerete már felületesebb,mint az első órákon bemutatottaké, ezért az ismeretek felelevenítésére, átismétlésére nagyobb hangsúlytkell fektetnünk!

  • www.tankonyvtar.hu

    Rendezések

    © Kurdi Zsombor, ÓE NIK 138

  • www.tankonyvtar.hu

    Buborékrendezés

    © Kurdi Zsombor, ÓE NIK 139

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Buborékrendezés • Feladat

    – Rendezzük egy sorozat elemeit növekvő sorrendbe.

    • Sorozathoz sorozatot rendel. • A rendezés megoldható helyben, vagy másolat készíthető a

    sorozat elemeiről.

    • Lépésszám – Legjobb eset: 0 – Legrosszabb eset: n2

    – Átlagos eset: ~n2

    – Függvényosztály: O(n2)

    140

  • Buborékrendezés

    www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK 141

    PresenterPresentation NotesMagyarázzuk el az ábra segítségével az algoritmus lépéseit!

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Feladat Buborékrendező algoritmussal rendezze a szamok.txt fájl

    tartalmát növekvő sorrendbe! Oldja meg a feladatot soros és párhuzamos algoritmussal is!

    Megjegyzés – A párhuzamos implementáció során célszerű az 1. órán megismert

    adatelosztást alkalmazni.

    142

    PresenterPresentation NotesPróbálkozzanak meg a hallgatók az önálló implementációval.Szükség esetén készítsük el közösen a programokat!

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Buborékrendezés (Soros) for (int i = számok.Length; i >= 2; --i) { for (int j = 0; j < i - 1; ++j) { if (számok[j] > számok[j + 1]) { int tmp = számok[j]; számok[j] = számok[j + 1]; számok[j + 1] = tmp; } } }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    143

    PresenterPresentation NotesSzükség esetén (a korábbi ábrát felhasználva) magyarázzuk el az implementációt!

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Paraméterstruktúra struct SzálParaméter { public int SzálIndex; public int[] Számok; public int StartIndex; public int Hossz; }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    144

    PresenterPresentation NotesA paraméterstruktúra az adatok elosztását támogatja a szálak között.

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Szálfüggvény private static void Szálfüggvény(object obj) { SzálParaméter param = (SzálParaméter)obj; for (int i = param.StartIndex + param.Hossz; i >= param.StartIndex + 2; --i) { for (int j = param.StartIndex; j < i - 1; ++j) { if (param.Számok[j] > param.Számok[j + 1]) { int tmp = param.Számok[j]; param.Számok[j] = param.Számok[j + 1]; param.Számok[j + 1] = tmp; } } } lock (sync) { ++lefutottSzálak; } }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    145

    PresenterPresentation NotesA szálfüggvény egy-egy adatszelet rendezését végzi el.

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Részeredmények összefésülése int[] indexek = new int[szálakSzáma]; for (int i = 0; i < szálakSzáma; ++i) indexek[i] = i * számok.Length / szálakSzáma; int[] eredmény = new int[számok.Length]; for (int i = 0; i < számok.Length; ++i) { int min = -1; for (int j = 0; j < szálakSzáma; ++j) { if (indexek[j] < (j + 1) * számok.Length / szálakSzáma && (min == -1 || számok[indexek[j]] < számok[indexek[min]])) { min = j; } } if (min >= 0) { eredmény[i] = számok[indexek[min]++]; } } Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    146

    PresenterPresentation NotesAz össefésülés során ‘szálakSzáma’ db rendezett sorozatot kell összefésülni.

  • www.tankonyvtar.hu

    ShellSort

    © Kurdi Zsombor, ÓE NIK 147

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    ShellSort/Shell rendezés • Feladat

    – Rendezzük egy sorozat elemeit növekvő sorrendbe.

    • Sorozathoz sorozatot rendel. • A rendezés megoldható helyben, vagy másolat készíthető a

    sorozat elemeiről. • A buborékrendezés javított változata.

    • Lépésszám

    – Függvényosztály: O(n * log2n)

    148

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Feladat ShellSort algoritmussal rendezze a szamok.txt fájl tartalmát

    növekvő sorrendbe! Oldja meg a feladatot soros és párhuzamos algoritmussal is!

    Megjegyzés – A párhuzamos implementáció során célszerű az 1. órán megismert

    adatelosztást alkalmazni.

    149

    PresenterPresentation NotesPróbálkozzanak meg a hallgatók az önálló implementációval.Szükség esetén készítsük el közösen a programokat!

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Shell rendezés (Soros) int inkremens = 3; while (inkremens > 0) { for (int i = 0; i < számok.Length; ++i) { int j = i; int tmp = számok[i]; while (j >= inkremens && számok[j - inkremens] > tmp) { számok[j] = számok[j - inkremens]; j -= inkremens; } számok[j] = tmp; } if (inkremens / 2 != 0) inkremens /= 2; else if (inkremens == 1) inkremens = 0; else inkremens = 1; } Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    150

    PresenterPresentation NotesSzükség esetén a programkód segítségével magyarázzuk el a Shell rendezés algoritmusának lépéseit!

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Shell rendezés (Párhuzamos) • Paraméterstruktúra

    – Azonos a buborékrendezésnél látottal

    • Szálfüggvény

    – A buborékrendezésnél látotthoz hasonló

    • Összefésülés

    – A buborékrendezésnél látotthoz hasonló

    151

  • www.tankonyvtar.hu

    HeapSort

    © Kurdi Zsombor, ÓE NIK 152

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    HeapSort/Kupac rendezés • Feladat

    – Rendezzük egy sorozat elemeit növekvő sorrendbe.

    • Sorozathoz sorozatot rendel. • A rendezés megoldható helyben, vagy másolat készíthető a

    sorozat elemeiről.

    • Lépésszám – Függvényosztály: O(n*logn)

    153

    PresenterPresentation NotesSzükség esetén ismételjük át a Heap adatszerkezetet, illetve az algoritmus lépéseit!

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Feladat HeapSort algoritmussal rendezze a szamok.txt fájl tartalmát

    növekvő sorrendbe! Oldja meg a feladatot soros és párhuzamos algoritmussal is!

    Megjegyzés – A párhuzamos implementáció során célszerű az 1. órán megismert

    adatelosztást alkalmazni.

    154

    PresenterPresentation NotesPróbálkozzanak meg a hallgatók az önálló implementációval.Szükség esetén készítsük el közösen a programokat!

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Heap sort (Soros) private static void Rendezés(int[] t, int start, int end) { int bal = start + (end - start) / 2; int jobb = end; int offset = start; while (bal >= start) { Süllyeszt(t, offset, bal, end); --bal; } while (jobb > start) { int tmp = t[jobb]; t[jobb] = t[start]; t[start] = tmp; --jobb; Süllyeszt(t, offset, start, jobb); } }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    155

    PresenterPresentation NotesA rendezés legkézenfekvőbb implementációja egy rekurzív függvény.A következő dián található a ‘Süllyeszt’ művelet!

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Heap sort (Soros) private static void Süllyeszt(int[] t, int offset, int start, int end) { int gyökér = start; while ((gyökér - offset) * 2 + 1

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Szálfüggvény private static void Szálfüggvény(object obj) { SzálParaméter param = (SzálParaméter)obj; Rendezés(param.Számok, param.StartIndex, param.StartIndex + param.Hossz - 1); lock (sync) { ++lefutottSzálak; } }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    157

    PresenterPresentation NotesA paraméter struktúra azonos az előbbi algoritmusnál használttal.

    A szálfüggvényben a korábban megismert rekurzív függvényt használjuk (a paraméter által meghatározott részadatokon).

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Összefésülés int[] indexek = new int[szálakSzáma]; for (int i = 0; i < szálakSzáma; ++i) indexek[i] = i * számok.Length / szálakSzáma; int[] eredmény = new int[számok.Length]; for (int i = 0; i < számok.Length; ++i) { int min = -1; for (int j = 0; j < szálakSzáma; ++j) { if (indexek[j] < (j + 1) * számok.Length / szálakSzáma && (min == -1 || számok[indexek[j]] <

    számok[indexek[min]])) min = j; } if (min >= 0) { eredmény[i] = számok[indexek[min]++]; } }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    158

    PresenterPresentation NotesAz összefésülés során most is ‘szálakSzáma’ db rendezett sorozatot kell öszefésülni.

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Házi feladat Próbálja ki a példaprogramokat! Kíséreljen meg javítani a

    párhuzamos változatok hatékonyságán!

    Megjegyzés – Lehetőség szerint a programokat futtassa egy-, illetve többprocesszoros

    gépeken!

    159

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Irodalomjegyzék • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein: Új algoritmusok, Scolar

    Kiadó, 2003.

    160

  • 6. óra Rendezések (2)

    Rendezések MergeSort QuickSort RADIX rendezés Irodalomjegyzék

    © Kurdi Zsombor, ÓE NIK www.tankonyvtar.hu 161

    PresenterPresentation NotesValamennyi a tartalomjegyzékben fersorolt algoritmus ismeretét feltételezhetjük a hallgatókról,mert azokat korábbi órákon már tanulták. Valószínűleg ezen algoritmusok ismerete már felületesebb,mint az első órákon bemutatottaké, ezért az ismeretek felelevenítésére, átismétlésére nagyobb hangsúlytkell fektetnünk!

  • Rendezések

    www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK 162

  • MergeSort

    www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK 163

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    MergeSort/Összefésüléses rendezés • Feladat

    – Rendezzük egy sorozat elemeit növekvő sorrendbe.

    • Sorozathoz sorozatot rendel . • A rendezés megoldható helyben, vagy másolat készíthető a

    sorozat elemeiről.

    • Lépésszám – Legjobb eset: 0 – Legrosszabb eset: n*logn

    – Átlagos eset: ~n*logn

    – Függvényosztály: O(n*logn)

    164

    PresenterPresentation NotesSzükség esetén ismételjük át az algoritmus lépéseit!

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Feladat MergeSort algoritmussal rendezze a szamok.txt fájl tartalmát

    növekvő sorrendbe! Oldja meg a feladatot soros és párhuzamos algoritmussal is!

    Megjegyzés – A szálak lefutásának ellenőrzéséhez célszerű valamilyen szemafór típust

    használni.

    165

    PresenterPresentation NotesPróbálkozzanak meg a hallgatók az önálló implementációval.Szükség esetén készítsük el közösen a programokat!

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    MergeSort (Soros) private static void Rendezés(int[] t, int bal, int jobb) { if (jobb > bal) { int közép = (jobb + bal) / 2; Rendezés(t, bal, közép); Rendezés(t, közép + 1, jobb); Összefésülés(t, bal, közép + 1, jobb); } }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    166

    PresenterPresentation NotesAz algoritmus legkézenfekvőbb implementációja egy rekurzív függvény.

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    MergeSort (Soros) private static void Összefésülés(int[] t, int bal, int közép, int jobb) { int[] tmptömb = new int[t.Length]; int tmpindex = bal; int balvég = közép - 1; int jobbvég = közép; int elemszám = jobb - bal + 1; while (bal

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    MergeSort (Soros) while (bal

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Paraméterstruktúra struct SzálParaméter { public int[] Számok; public int Bal; public int Jobb; public EventWaitHandle Szemafor; }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    169

    PresenterPresentation NotesA paraméterstruktúra eltér a korábban látottaktól:–Meghatározza a rendezendő részt.–Tartalmaz egy szemafort, amely segítségével ellenőrizhető, hogy az adott szál befejezte-e a rendezést.

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Szálfüggvény private static void Szálfüggvény(object obj) { SzálParaméter param = (SzálParaméter)obj; if (param.Jobb > param.Bal) { int közép = (param.Bal + param.Jobb) / 2; SzálParaméter paraméter1; paraméter1.Számok = param.Számok; paraméter1.Bal = param.Bal; paraméter1.Jobb = közép; paraméter1.Szemafor = new ManualResetEvent(); ThreadPool.QueueUserWorkItem(new WaitCallback(Szálfüggvény), paraméter1); SzálParaméter paraméter2; paraméter2.Számok = param.Számok; paraméter2.Bal = közép + 1; paraméter2.Jobb = param.Jobb; paraméter2.Szemafor = new ManualResetEvent();

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    170

    PresenterPresentation NotesA szálfüggvényben – a soros implementációhoz hasonlóan – rekurzívan két részre osztjuk a rendezendő részt és azokon végezzükel a rendezést úgy, hogy újabb szálakat indítunk. Amikor az a 2 szál elvégezte a munkáját, akkor az aktuális részadatok rendezettségétaz összefésüléssel biztosítjuk.

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Szálfüggvény ThreadPool.QueueUserWorkItem(new WaitCallback (Szálfüggvény), paraméter2); WaitHandle.WaitAll(new WaitHandle [] { paraméter1.Szemafor, paraméter2.Szemafor }); Összefésülés(param.Számok, param.Bal, közép + 1, param.Jobb); } param.Szemafor.Set(); }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    171

    PresenterPresentation NotesAz implementáció mellékhatása, hogy nincs szükség összefésülésre.

  • QuickSort

    www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK 172

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    QuickSort/Gyorsrendezés • Feladat

    – Rendezzük egy sorozat elemeit növekvő sorrendbe.

    • Sorozathoz sorozatot rendel. • A rendezés megoldható helyben, vagy másolat készíthető a

    sorozat elemeiről.

    • Lépésszám – Legjobb eset: 0 – Legrosszabb eset: n * logn

    – Átlagos eset: ~n * logn

    – Függvényosztály: O(n * logn)

    173

    PresenterPresentation NotesSzükség esetén ismételjük át az algoritmus lépéseit!

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Feladat QuickSort algoritmussal rendezze a szamok.txt fájl tartalmát

    növekvő sorrendbe! Oldja meg a feladatot soros és párhuzamos algoritmussal is!

    Megjegyzés – A párhuzamos implementáció során célszerű a visszalépéses keresésnél

    megismert rekurzív szálindítási technikát alkalmazni.

    174

    PresenterPresentation NotesPróbálkozzanak meg a hallgatók az önálló implementációval.Szükség esetén készítsük el közösen a programokat!

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    QuickSort (Soros) private static void Rendezés(int[] t, int bal, int jobb) { int balelem = t[bal]; int balindex = bal; int jobbindex = jobb; while (bal < jobb) { while (bal < jobb && t[jobb] >= balelem) --jobb; if (bal != jobb) { t[bal] = t[jobb]; ++bal; } while (bal < jobb && t[bal]

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    QuickSort (Soros) if (bal != jobb) { t[jobb] = t[bal]; --jobb; } } t[bal] = balelem; if (balindex < bal) Rendezés(t, balindex, bal - 1); if (jobbindex > bal) Rendezés(t, bal + 1, jobbindex); }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    176

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Paraméterstruktúra struct SzálParaméter { public int[] Számok; public int Bal; public int Jobb; }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    177

    PresenterPresentation NotesA paraméterstruktúra illeszkedik az algoritmus tömbkezeléséhez.

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Szálfüggvény private static void Szálfüggvény(object obj) { SzálParaméter param = (SzálParaméter)obj; int balelem = param.Számok[param.Bal]; int balindex = param.Bal; int jobbindex = param.Jobb; // Rendezés if (balindex < param.Bal) { SzálParaméter paraméter; paraméter.Számok = param.Számok; paraméter.Bal = balindex; paraméter.Jobb = param.Bal - 1; lock (syncElindított) { ++elindítottSzálak; }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    178

    PresenterPresentation NotesA szálfüggvény hasonló az előző algoritmus implementációjában használthoz, de itt nincs szükgés összefésülésre, ezértnem szükséges az elindított szálak lefutásának bevárása.

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Szálfüggvény ThreadPool.QueueUserWorkItem(new WaitCallback(Szálfüggvény), paraméter); } if (jobbindex > param.Bal) { SzálParaméter paraméter; paraméter.Számok = param.Számok; paraméter.Bal = param.Bal + 1; paraméter.Jobb = jobbindex; lock (syncElindított) { ++elindítottSzálak; } ThreadPool.QueueUserWorkItem(new WaitCallback(Szálfüggvény), paraméter); } lock (syncLefutott) { ++lefutottSzálak; } }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    179

  • RADIX rendezés

    www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK 180

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    RADIX rendezés • Feladat

    – Rendezzük egy sorozat elemeit növekvő sorrendbe.

    • Sorozathoz sorozatot rendel. • A rendezés megoldható helyben, vagy másolat készíthető a

    sorozat elemeiről. • A Vödrös rendezés speciális formája.

    – Azonos hosszúságú sorozatok rendezésére használható.

    • Lépésszám

    – Függvényosztály: Θ(n)

    181

    PresenterPresentation NotesSzükség esetén ismételjük át az algoritmus lépéseit!

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Feladat RADIX/Vödrös rendezés algoritmussal rendezze a szamok.txt fájl

    tartalmát növekvő sorrendbe! Oldja meg a feladatot soros és párhuzamos algoritmussal is!

    182

    PresenterPresentation NotesPróbálkozzanak meg a hallgatók az önálló implementációval.Szükség esetén készítsük el közösen a programokat!

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    RADIX (Soros) for (int i = 0; i < lépésekSzáma; ++i) { for (int j = 0; j < számok.Length; ++j) tárolók[Számjegy(számok[j], i)].Enqueue(számok[j]); int index = 0; for (int j = 0; j < tárolók.Length; ++j) { while (tárolók[j].Count > 0) számok[index++] = tárolók[j].Dequeue(); } }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    183

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Paraméterstruktúra struct SzálParaméter { public int[] Számok; public int StartIndex; public int Hossz; public int Lépés; public int[] Tárolók; }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    184

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Szálfüggvény private static void Szálfüggvény(object obj) { SzálParaméter param = (SzálParaméter)obj; for (int i = param.StartIndex; i < param.StartIndex + param.Hossz; ++i) { lock (param.Tárolók) { ++param.Tárolók[param.Számok[i]]; } } lock (syncLefutott) { ++lefutottSzálak; } }

    Program.cs

    1 2 3 4 5 6 7 8 9

    10 11 12 13 14 15 16 17 18 19 20 21 22 23

    185

  • www.tankonyvtar.hu © Kurdi Zsombor, ÓE NIK

    Rendezett sorozat előállítása for (int i = 0, index = 0; i < tárolók.Length; ++i) { for (int j = 0; j < tárolók[i]; ++j) számok[index++] = i; }

    Program.cs