Rekurzió 2. Belépő a tudás közösségébe Informatika szakköri segédanyag

Hasonló dokumentumok
Informatikai tehetséggondozás:

Informatikai tehetséggondozás:

Algoritmizálás, adatmodellezés tanítása 11. előadás. (Horváth Gyula előadása alapján)

Rekurzió. (Horváth Gyula és Szlávi Péter előadásai felhasználásával)

Visszalépéses maximumkiválasztás

Visszalépéses kiválogatás

Rekurzió. (Horváth Gyula és Szlávi Péter előadásai. felhasználásával)

Feladatmegoldási stratégiák

Rekurzív algoritmusok

Rekurzió. (Horváth Gyula és Szlávi Péter előadásai felhasználásával)

Visszalépéses keresés korlátozással

Kombinatorikai algoritmusok. (Horváth Gyula és Szlávi Péter előadásai felhasználásával)

Kombinatorikai algoritmusok

Adatszerkezetek II. 10. előadás

Diszkrét matematika 1.

Diszkrét matematika 1.

Nagy Gábor compalg.inf.elte.hu/ nagy ősz

Dinamikus programozás II.

ARCHIMEDES MATEMATIKA VERSENY

5. Rekurzió és iteráció (Rekurzív programok átírása nemrekurzívvá)

A 2017/2018 tanévi Országos Középiskolai Tanulmányi Verseny első fordulójának feladatai. INFORMATIKA II. (programozás) kategória

FPI matek szakkör 8. évf. 4. szakkör órai feladatok megoldásokkal. 4. szakkör, október. 20. Az órai feladatok megoldása

Összetett programozási tételek 2.

Pásztor Attila. Algoritmizálás és programozás tankönyv az emeltszintű érettségihez

A 2009/2010 tanévi Országos Középiskolai Tanulmányi Verseny első forduló feladatainak megoldása. INFORMATIKÁBÓL II. (programozás) kategóriában

Sorozatok I. Brósch Zoltán (Debreceni Egyetem Kossuth Lajos Gyakorló Gimnáziuma)

Programozás alapjai. 6. gyakorlat Futásidő, rekurzió, feladatmegoldás

A programozás alapjai 1 Rekurzió

A 2014/2015 tanévi Országos Középiskolai Tanulmányi Verseny döntő forduló javítási-értékelési útmutató. INFORMATIKA II. (programozás) kategória

Összetett programozási tételek

Információk. Ismétlés II. Ismétlés. Ismétlés III. A PROGRAMOZÁS ALAPJAI 2. Készítette: Vénné Meskó Katalin. Algoritmus. Algoritmus ábrázolása

Információs Technológia

Nyugat-magyarországi Egyetem Geoinformatikai Kara. Prof. Dr. Závoti József. Matematika III. 1. MA3-1 modul. Kombinatorika

Játék a szavakkal. Ismétléses nélküli kombináció: n különböző elem közül választunk ki k darabot úgy, hogy egy elemet csak egyszer

Felvételi tematika INFORMATIKA

A 2013/2014 tanévi Országos Középiskolai Tanulmányi Verseny első forduló javítási-értékelési útmutató. INFORMATIKA II. (programozás) kategória

Algoritmizálás, adatmodellezés tanítása 8. előadás

Alkalmazott modul: Programozás 4. előadás. Procedurális programozás: iteratív és rekurzív alprogramok. Alprogramok. Alprogramok.

INFORMATIKA javítókulcs 2016

A félév során előkerülő témakörök

2018, Diszkrét matematika

Bevezetés a matematikába (2009. ősz) 1. röpdolgozat

2010. október 12. Dr. Vincze Szilvia

Algoritmizálás, adatmodellezés tanítása 1. előadás

Informatikai tehetséggondozás:

Definíció n egymástól megkülönböztethető elem egy sorrendjét az n elem egy (ismétlés nélküli) permutációjának nevezzük.

Multihalmaz, intervallumhalmaz

Sorozatok határértéke SOROZAT FOGALMA, MEGADÁSA, ÁBRÁZOLÁSA; KORLÁTOS ÉS MONOTON SOROZATOK

Arany Dániel Matematikai Tanulóverseny 2014/2015-ös tanév első (iskolai) forduló Haladók II. kategória

Szittyai István december 8. SZTE Bolyai Intézet. Szittyai István (NLG, Hmvh) Partíciók , Bolyai, Szeged 1 / 24

Analízis előadás és gyakorlat vázlat

Rekurzió. (Horváth Gyula és Szlávi Péter előadásai felhasználásával)

BABEŞ-BOLYAI TUDOMÁNYEGYETEM MATEMATIKA-INFORMATIKA KAR Felvételi verseny - minta Informatika írásbeli

1.1. Alapfeladatok. hogy F 1 = 1, F 2 = 1 és általában F n+2 = F n+1 + F n (mert a jobboldali ág egy szinttel lennebb van, mint a baloldali).

ARANYMETSZÉS. - érettségi dolgozat védése analízis és algebrából - Készítette: Szénási Eszter Mentor: Dr. Péics Hajnalka június 11.

Adatszerkezetek I. 7. előadás. (Horváth Gyula anyagai felhasználásával)

Oktatási Hivatal. A 2014/2015 tanévi Országos Középiskolai Tanulmányi Verseny döntő fordulójának feladatai. II. (programozás) kategória

Programozás alapjai II. (7. ea) C++ Speciális adatszerkezetek. Tömbök. Kiegészítő anyag: speciális adatszerkezetek

10. Egy családfában csak a férfiakat és fiúgyerekeket ábrázoljuk, egy közös ősből kiindulva. Készíts

A rész (30 pont) A.1. Vajon mit csinál? (5 pont) A generál(n) algoritmus egy n természetes számot dolgoz fel (0 < n < 100).

A 2015/2016. tanévi Országos Középiskolai Tanulmányi Verseny döntő forduló MATEMATIKA III. KATEGÓRIA (a speciális tanterv szerint haladó gimnazisták)

2009. májusi matematika érettségi közép szint

S Z A K D O L GO Z AT

Előfeltétel: legalább elégséges jegy Diszkrét matematika II. (GEMAK122B) tárgyból

8. Előadás. Megyesi László: Lineáris algebra, , oldal. 8. előadás Mátrix rangja, Homogén lineáris egyenletrendszer

Biomatematika 2 Orvosi biometria

Rekurzió. Dr. Iványi Péter

2015, Diszkrét matematika

Bevezetés az informatikába

SCILAB programcsomag segítségével

26. MINIMÁLIS KÖLTSÉGŰ UTAK MINDEN CSÚCSPÁRRA

KOVÁCS BÉLA, MATEMATIKA I.

BACKTRACKING Visszalépéses keresés

Nagy Gábor compalg.inf.elte.hu/ nagy ősz

Hatékonyság 1. előadás

Funkcionálanalízis. n=1. n=1. x n y n. n=1

Rekurzió. Működése, programtranszformációk. Programozás II. előadás. Szénási Sándor.

0-49 pont: elégtelen, pont: elégséges, pont: közepes, pont: jó, pont: jeles

Algoritmuselmélet. Legrövidebb utak, Bellmann-Ford, Dijkstra. Katona Gyula Y.

Programozási nyelvek 3. előadás

Speciális adatszerkezetek. Programozás alapjai II. (8. ea) C++ Tömbök. Tömbök/2. N dimenziós tömb. Nagyméretű ritka tömbök

2015, Diszkrét matematika

Informatikai tehetséggondozás:

Adatszerkezetek I. 8. előadás. (Horváth Gyula anyagai felhasználásával)

Programozás. (GKxB_INTM021) Dr. Hatwágner F. Miklós március 3. Széchenyi István Egyetem, Gy r

NULLADIK MATEMATIKA ZÁRTHELYI

INFORMATIKA tétel 2019

24. tétel. Kombinatorika. A grá fok.

Tanmenet a évf. fakultációs csoport MATEMATIKA tantárgyának tanításához

Matematika szóbeli érettségi témakörök 2016/2017-es tanév őszi vizsgaidőszak

A 2007/2008 tanévi Országos Középiskolai Tanulmányi Verseny első forduló feladatainak megoldása. II. (programozás) kategória

Shannon és Huffman kód konstrukció tetszőleges. véges test felett

Adatszerkezetek I. 4. előadás

Osztályozóvizsga és javítóvizsga témakörei Matematika 9. évfolyam

Próbaérettségi feladatsor_b NÉV: osztály Elért pont:

A 2010/2011 tanévi Országos Középiskolai Tanulmányi Verseny első forduló feladatainak megoldása. INFORMATIKÁBÓL II. (programozás) kategóriában

Adatszerkezetek II. 3. előadás

A 2017/2018 tanévi Országos Középiskolai Tanulmányi Verseny második fordulójának feladatai. INFORMATIKA II. (programozás) kategória

A sorozat fogalma. függvényeket sorozatoknak nevezzük. Amennyiben az értékkészlet. az értékkészlet a komplex számok halmaza, akkor komplex

Számelmélet Megoldások

Átírás:

Belépő a tudás közösségébe Informatika szakköri segédanyag Bende Imre, Heizlerné Bakonyi Viktória, Menyhárt László, Szlávi Péter, Törley Gábor, Zsakó László Szerkesztő: Abonyi-Tóth Andor, Zsakó László A kiadvány A felsőoktatásba bekerülést elősegítő készségfejlesztő és kommunikációs programok megvalósítása, valamint az MTMI szakok népszerűsítése a felsőoktatásban (EFOP-3.4.4-16-2017-006) című pályázat keretében készült 2018-ban. 0

Bajok a rekurzióval Hely: nagyra dagadt memóriaméret az ismétlődő eljáráshívások miatt. Idő: a többszörösen ismétlődő hívások felesleges kiszámolása. Pl. Fibonacci-számoknál: F(n) F(n-1) F(n-2) F(n-2) F(n-3) F(n-3) F(n-4) F(n-3) F(n-4) F(n-4) F(n-5) F(n-4) F(n-5) F(n-5) F(n-6) Az ábráról látható: F(N) kiszámolásai száma: 1 F(N-1) kiszámolásai száma: 1 F(N-2) kiszámolásai száma: 2 F(N-3) kiszámolásai száma: 3 F(N-4) kiszámolásai száma: 5 ebből következően F(N-5) kiszámolásai száma: 8 Ezek a kiszámolási számok éppen a Fibonacci számok. Egy kis matematika: Legyen r(n):=az N. Fibonacci-szám kiszámításához szükséges függvényhívások száma! Állítás: a) r(i)=f(i+1)+f(i)+f(i-1)-1, ha i>1 r(0):=1, r(1):=1, r(i):=r(i-1)+r(i-2)+1 b) r(i)=2*f(i+1)-1, ahol F(i)=az i. Fibonacci-szám. Megoldási ötlet: amit már kiszámoltunk egyszer, azt ne számoljuk újra! Tároljuk a már kiszámolt értékeket memorizáljuk, s ha szükségünk van rájuk, használjuk fel őket! 2

A Fibonacci-számok A rekurzív függvények matematikai elméletében éppúgy ismert, mint a biológiában a Fibonacci olasz matematikusról elnevezett számsorozat. Azt vizsgálta, hogy egy nyúlpár alapította nyúlnemzetség adott idő alatt mekkora létszámúra növekszik, figyelembe véve, hogy a leszármazottak is alaposan besegítenek a létszámnövelésbe. Ha a szaporodás eléggé szabályosan történik, akkor az új generáció létszámát az előzőek ismeretében könnyen kiszámíthatjuk. Szerinte az új generáció növekedését az előző 2 generáció gyerekei teszik ki. E mögött az a feltételezés húzódik meg, hogy minden nyúlpár egyszerre éppen 2 utóddal járul a népességhez, és e szokásukat születésüket követő 2 egymásutáni időpontban gyakorolják (mert mondjuk mielőtt a harmadik szaporodásra sor kerülhetne, fazékba kerülnek). Definíciója Példa Fib n a Fibonacci-szám sorozat első néhány tagja 0,1,1,2,3,5,8,13,21,34,55,... 0 ha n 0 1 ha n 1 Fib n 1 Fib n 2 ha n 1 Fib(N): Elágazás N=0 esetén Fib:=0 N=1 esetén Fib:=1 egyéb esetben Fib:=Fib(N-1)+Fib(N-2) A memorizálásos megoldásban F(i) 0 jelenti, ha már kiszámoltuk az i-edik Fibonacci számot. A függvény hívása előtt az F vektor elemei értékét -1-re kell állítani! Fib(N): Ha F(N)<0 akkor Elágazás N=0 esetén F(N):=0 N=1 esetén F(N):=1 egyéb esetben F(N):=Fib(N-1)+Fib(N-2) Fib:=F(N) Minta kódok. C++ cpp/fibonacci/feladat.cpp C# cs/fibonacci/feladat.cs Java Pascal Python java/fibonacci/feladat.java pas/fibonacci/feladat.pas py/fibonacci/feladat.py 3

Járdakövezés Számítsuk ki, hogy hányféleképpen lehet egy n egység méretű járdát kikövezni 1x1, 1x2 és 1x3 méretű lapokkal! Az első helyre tehetünk 1x1-es lapot: Az első helyre tehetünk 1x2-es lapot: Az első helyre tehetünk 1x3-as lapot: Az első esetben n-1, a másodikban n-2-t, a harmadikban pedig n-3 cellát kell még lefednünk. Azaz az n cella lefedéseinek Lefed(n) száma Lefed(n-1)+Lefed(n-2)+Lefed(n-3). Lefed(N): Elágazás N=0 esetén Lefed:=0 N=1 esetén Lefed:=1 N=2 esetén Lefed:=2 egyéb esetben Lefed:=Lefed(N-1)+Lefed(N-2)+Lefed(N-3) Itt már három rekurzív hívás van korábbi N értékekre, még nagyobb lehet az átfedés a kiszámolásokban. L(i)=-1 jelenti, hogy L(i)-t még nem számoltuk ki, L(i) 0 jelenti, hogy már kiszámoltuk. Lefed(N): Ha L(N)<0 akkor Elágazás N=0 esetén L(N):=0 N=1 esetén L(N):=1 N=2 esetén L(N):=2 egyéb esetben L(N):=Lefed(N-1)+Lefed(N-2)+Lefed(N-3) Lefed:=L(N) 4

A feladat megoldása tesztelhető az elkészült forráskód feltöltésével itt: Weboldal Szint Téma Feladat https://mester.inf.elte.hu/ Haladó Rekurzív kiszámítás Járda 1 1x1,1x2,1x3 Binomiális együtthatók Egy véges halmaz, melynek N darabszámú elemeiből K elemszámú halmazokat (kombinatorika nevén osztályokat) akarunk mindenféle módon képezni (és minden elem csak egyszer fordul elő). Ezt úgy hívjuk, hogy n elem k-ad osztályú ismétlés nélküli kombinációja. Ezen kombinációk száma megegyezik a matematikából máshonnan is ismert binomiális együtthatókkal. A binomiális együtthatókat a következő képlettel definiálhatjuk: n n! k k! n k! Ennek kiszámítása hosszú programot igényelne, próbálkozzunk inkább egy másik kiszámítási módszerrel! Ehhez nézzük meg e számok elrendezését, a Pascal háromszöget: 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 1 6 15 20 15 6 1 1 7 21 35 35 21 7 1 1 8 28 56 70 56 28 8 1 1 9 36 84 126 126 84 36 9 1 1 10 45 120 210 252 210 120 45 10 1 1 11 55 165 330 462 462 330 165 55 11 1 1 12 66 220 495 792 924 792 495 220 66 12 1 Felfedezhetjük, hogy a fenti táblázatban minden szám a fölötte levő két szám összege, azaz N elemből K elem választása leírható az alábbi módon: az első elemet választjuk, majd még N-1 elemből választunk K-1 elemet. vagy az első elemet nem választjuk és a maradék N-1 elemből választunk K elemet. Bin(n,k): Ha k=0 vagy k=n akkor Bin:=1 különben Bin:=Bin(n-1,k)+Bin(n-1,k-1) 5

Adott n és k értékre az alábbi téglalapbeli elemeket számoljuk ki, de mindegyiket annyiszor, ahányféleképpen az (n.k) elemből felfelé haladva eljuthatunk hozzájuk. 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 1 6 15 20 15 6 1 1 7 21 35 35 21 7 1 1 8 28 56 70 56 28 8 1 1 9 36 84 126 126 84 36 9 1 1 10 45 120 210 252 210 120 45 10 1 1 11 55 165 330 462 462 330 165 55 11 1 1 12 66 220 495 792 924 792 495 220 66 12 1 Itt is memorizálunk, B(n,k)=-1 jelentse azt, hogy (n,k)-ra még nem számoltuk ki a Bin függvény értékét, B(n,k) 0 pedig azt, hogy már kiszámoltuk: Bin(n,k): Ha B(n,k)<0 akkor Ha k=0 vagy k=n akkor B(n,k):=1 különben B(n,k):=Bin(n-1,k)+Bin(n-1,k-1) Bin:=B(n,k) Minta kódok. C++ cpp/binomialis/feladat.cpp C# cs/binomialis/feladat.cs Java Pascal Python java/binomialis/feladat.java pas/binomialis/feladat.pas py/binomialis/feladat.py 6

Ősök N ember mindegyikéről tudjuk, hogy ki az anyja (a két szülőből így csak az egyiket kell tárolni), az embereket sorszámukkal azonosítjuk. Mindenkinek egyértelműen 1 anyja lehet, emiatt az adatokat egyetlen vektorban tárolhatjuk: Anya(i) jelenti az i. ember anyjának sorszámát. Akinek nem ismerjük az anyját, annál ez a sorszám legyen 0! A kapcsolatokból egy ilyen hálózat épülhet fel: 12 10 11 7 8 9 1 2 3 4 5 6 Adjuk meg egy adott ember (A) legközelebbi ősét! Az ős saját maga, ha az anyját nem ismerjük. Ha az anyját ismerjük, akkor a legrégebbi őse megegyezik az anyja legrégebbi ősével megtaláltuk a rekurziót: Ős(A): Ha Anya(A)=0 akkor Ős:=A különben Ős:=Ős(Anya(A)) Ez a rekurzív függvény csak egyszer hívja magát, azaz többször ugyanazzal a paraméterrel biztos nem hívja meg magát, nincs értelme memorizálással foglalkozni. Módosítsuk a feladatot: adjuk meg két adott ember (A és B) legrégebbi közös ősét, ha van! KözösŐs(A,B): x:=őse(a) y:=őse(b) Ha x=y akkor KözösŐs:=x különben KözösŐs:=0 Itt már felmerülhet a többszöri kiszámítás. Ha az előző példa szerint 1 és 2 közös ősét keressük, akkor az első Őse függvényhívás megadja a 12 sorszámú embert, a második függvényhívás pedig ebben a hálóban újra felmegy a 12-ig. A hálón azonban az látható, hogy ha másodszor a 7-ig elértünk, akkor már tudjuk, hogy a legrégebbi 12 a közös ős. 7

12 10 11 7 8 9 Tehát memorizáljuk A őseit! 1 2 3 Ős(A): Volt(A):=igaz Ha Anya(A)=0 akkor Ős:=A különben Ős:=Ős(Anya(A)) 4 5 6 VanKözös(B): Ha Volt(B) akkor VanKözös:=igaz különben Ha Anya(B)=0 akkor VanKözös:=hamis különben VanKözös:=VanKözös(Anya(B)) KözösŐs(A,B): x:=ős(a) Ha VanKözös(B) akkor KözösŐs:=x különben KözösŐs:=0 A feladat megoldása tesztelhető az elkészült forráskód feltöltésével itt: Weboldal Szint Téma Feladat https://mester.inf.elte.hu/ Haladó Rekurzív adatszerkezetek 63. Közös ősök Ősök száma Számoljuk ki az előző példát folytatva egy adott ember (A) ősei számát! Ha nem ismerjük az anyját, akkor ez a szám 0, ha ismerjük, akkor neki az anyja ősei számánál eggyel több őse van: 8

Ősszám(A): Ha Anya(A)=0 akkor Ősszám:=0 különben Ősszám:=Ősszám(Anya(A))+1 Itt is egyetlen rekurzív hívás van, azaz memorizálásra nincs szükség. Módosítsuk a feladatot, számoljuk ki két ember (A,B) közös ősei számát! A közös ősök halmaza az A és a B ősei halmazának közös része (metszete) lesz. Az alapmegoldásunk ennek meghatározására nem alkalmas két ember ősei számából ez a szám nem határozható meg. Itt tehát mindenképpen nem csak hatékonysági szempontból szükségünk van memorizálásra. 12:0 10:1 11 7:2 8 9 1: 3 2 3 4 5 6 A megoldásban az ősök számának meghatározása közben számoljuk ki az ősök ősei számát is! Ősszám(A): Ha Anya(A)=0 akkor Db(A):=0 különben Db(A):=Ősszám(Anya(A))+1 Ősszám:=Db(A) Ebben az esetben a B-vel közös ősök számát pontosan akkor tudjuk meg, amikor B-ből elérjük az első közös őst! KözösŐsszám(B): Ha Db(B) 0 akkor KözösŐsszám:=Db(B)+1 különben Ha Anya(B)=0 akkor KözösŐsszám:=0 különben KözösŐsszám:= KözösŐsszám(Anya(B)) KözösŐsökSzáma(A,B): x:=ősszám(a) KözösŐsökSzáma:=KözösŐsszám(B) 9

A feladat megoldása tesztelhető az elkészült forráskód feltöltésével itt: Weboldal Szint Téma Feladat https://mester.inf.elte.hu/ Haladó Rekurzív adatszerkezetek Közös ősök száma Ősök távolsága A következő feladatban azt szeretnénk tudni, hogy egy adott ember milyen távolságra van a legrégebbi ősétől. Nem meglepően ez ugyanaz a feladat, mint az ősök száma: Távolság(A): Ha Anya(A)=0 akkor Távolság:=0 különben Távolság:=Távolság(Anya(A))+1 Ha azonban arra lennénk kíváncsiak, hogy két ember legközelebbi közös őse milyen távol van tőlük (azaz a két távolság összege érdekel), akkor ez az információ (és ezzel együtt ez a megoldás) nem elégséges. Memorizálnunk kell, de nem az ősök számát, hanem az adott embertől vett távolságot : Távolság(A,i): TAV(A):=i Ha Anya(A)=0 akkor Távolság:=0 különben Távolság:=Távolság(Anya(A),i+1)+1 12:3 10:2 11 7:1 8 9 1:0 2 3 4 5 6 Ekkor a közös ős távolság két távolság összegeként számolandó: KözösTávolság(B,i): Ha TAV(B) 0 akkor KözösTávolság:=TAV(B)+i különben Ha Anya(B)=0 akkor KözösTávolság:=-1 különben KözösTávolság:=KözösTávolság(Anya(B),i+1) 10

A feladat megoldása tesztelhető az elkészült forráskód feltöltésével itt: Weboldal https://mester.inf.elte.hu/ Szint??? Téma??? Feladat Legtöbb ember őse Ez az a feladat, ami csak memorizálással oldható meg azt kell tárolni mindenkiről, hogy hány embernek őse. Praktikus lenne az emberek olyan sorszámozását megadni, ahol tudjuk, hogy kik azok, akik a hálóban alul vannak, mert belőlük érdemes elindulni felfelé. 12 10 7 11 8 9 1 2 3 4 5 6 Itt az 1..7, általánosan fogalmazva az 1..K sorszámú emberekből kell kiindulni. Utódszám(A,x): Ha Anya(A)=0 akkor Db(A):=Db(A)+x különben Db(A):=Db(A)+x; Utódszám(Anya(A),x+1) Eljárás vége. LegtöbbUtód(max): Ciklus i=1-től K-ig Utódszám(i,0) Ciklus vége max:=1 Ciklus i=2-től N-ig Ha Db(i)>Db(max) akkor max:=i Ciklus vége Eljárás vége. 11

A feladat megoldása tesztelhető az elkészült forráskód feltöltésével itt: Weboldal https://mester.inf.elte.hu/ Szint??? Téma??? Feladat 12