Fibonacci-sorozat

Fibonacci logó

Fibonacci logóMa van (november 23.) a Fibonacci nap (újra). Fibonacci középkori matematikus volt, ő tette közismertté a Fibonacci-sorozat-ot. A (0), 1, 1, 2, 3, 5, 8, 13, 21, 34, sorozat igen népszerű azok közében is, akik programozást tanulnak. A sorozat első két eleme 1 és 1 (ha szükséges, akkor nulladik elemmel is dolgozhatunk), és minden további elem az előző két elem összege.

Korábban is blogoltak a kollégáim a témában:

Következzen most az én öt különböző megoldásom Java forráskódja, rövid magyarázattal. Mindegyik a Fibonacci-sorozat első tíz elemét állítja elő.

1. megoldás

Az első megoldás generikus listát épít. Az első két elemet elhelyezi a lista elején ( list.add(1)). Ezek a lista nulladik és első elemei lesznek. Ezután a metódus a maradék 8 elemmel 2-től n-1-ig fiktív indexként hivatkozva az előző két elem összegeként ( list.get(i-1)+list.get(i-2)) index nélkül bővíti a listát.

2. megoldás

A második megoldás a tipikusan nem hatékony rekurzív módszert implementálja. A rekurzív fib() függvény a sorozat egyetlen elemét adja vissza, amit (a függvényt) a ciklus sokszor meghív ahelyett, hogy a ciklus vagy a rekurzió „emlékezne” az előző elemekre.

3. megoldás

A harmadik megoldás funkcionális nyelvi elemeket (Stream API) használ. A folyamba kétdimenziós tömbre történő hivatkozással ( f-> new int[] ), közvetlen hozzárendeléssel/leképezéssel ( map()), kerülnek be a sorozat elemei.

4. megoldás

A negyedik megoldás a Fibonacci-számok zárt alakját használja. Másképpen ez a Binet-formula:

Ezzel a képlettel a sorozat elemei közvetlenül megadhatók, azaz nem szükséges más elemekre való hivatkozás. A ciklus adja meg, hogy a sorozat 1-10-ig indexelt elemei szükségesek.

5. megoldás

Az ötödik megoldás szintén Stream API-t használ. Először előállít egy sorozatot 1-10-ig, amiket a leképezésnél ( map()) inputként használ és alkalmazza rájuk a Binet-formulát. Hagyományos ciklus utasítás nem szükséges.

Eredmény

Mindegyik megoldás a konzolra írja szövegesen az eredményt, azaz a Fibonacci-sorozat első tíz elemét: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55. Érdemes elemezni a hatékonyság klasszikus három szempontja (időigény/lépésszám, tárigény, bonyolultság) alapján a különböző megoldásokat. Ezek mérésével könnyen kiegészíthetők a fenti metódusok, vagy az azokat meghívó osztályban a vezérlés.

A bejegyzéshez tartozó teljes forráskódot ILIAS e-learning tananyagban tesszük elérhetővé tanfolyamaink résztvevői számára.

A feladat a Java SE szoftverfejlesztő tanfolyam szakmai moduljának 9-12. óra: Metódusok, rekurzió és 17-28. óra Objektumorientált programozás alkalmaihoz kötődik.

Fibonacci-spirál

Fibonacci logó

Fibonacci logóA Fibonacci-spirál a népszerű Fibonacci-sorozat elemei által meghatározott oldalhosszúságú négyzetekbe rajzolt maximális sugarú negyedkörök megfelelően összeillesztett darabjaiból/sorozatából áll. Sokszor hasonlítják az arany spirálhoz (jól közelíti), amely az aranymetszéshez kötődik.

A Fibonacci-spirál

Vegyük a Fibonacci-sorozat első 10 elemét! Rajzoljuk egymás mellé az alábbi elrendezésben belülről kifelé haladva az 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 oldalhosszúságú négyzeteket (az alábbi ábrán vékony sárgával jelölve). Piros színnel rajzoljuk bele a négyzetekbe a négyzet oldalhosszával megegyező sugarú negyedköröket. A negyedkörök megfelelő elrendezésben folytonos görbét alkotnak, és ezt nevezzük Fibonacci-spirálnak (az alábbi ábrán vastag pirossal jelölve).

Fibonacci-spirál 1

A rajzolás bármeddig folytatható, mert a sorozat végtelen, a négyzetek illeszkednek és az ábra rekurzív, önhasonló. Az alábbi animáció mutatja, hogyan alakul a spirál a nézőpont közelítésével. A viselkedés távolítás során is azonos lenne.

Fibonacci-spirál 2

Korábban blogoltunk már a Fibonacci napról, amelyet minden évben november 23-án ünneplünk. A sorozat első néhány eleméből összeáll a 11.23. és értelmezhető dátumként. Most nem a sorozat elemeinek előállítására fókuszálunk, hanem arra, hogy ezekből felépítsük a Fibonacci-spirált.

Készítsünk Java programot!

Grafikus felületű Java programot készítünk, amely 21 animációs fázisban mutatja be a Fibonacci-sorozat első 10 eleméből álló Fibonacci-spirál felépítését. A rajzolás fázisai:

  • Az 1. fázis a kiindulópontként tekinthető fehér, üres rajzlap. A rajzlap fekvő, mérete 890*550 pixel, amelyre éppen elfér a 10 negyedkörből álló spirál.
  • A 2-11. fázisban megfelelő pozícióba/koordinátákra kerülnek fel az ábra vázát alkotó négyzetek, belülről kifelé haladva. A négyzetek oldalainak hosszúsága a sorozat elemeinek megfelelő. A szomszédos négyzetek különböző színekkel kitöltöttek és mindegyikben megjelenik a sorozat megfelelő eleme.
  • A 12-21. fázisban – szintén belülről kifelé haladva – a négyzetek törlődnek és helyükre a spirált alkotó negyedkörök kerülnek fekete színnel. A 21. fázist tekintjük végeredménynek.

A fázisok kézzel, nyilakkal jelölt (Első, Előző, Következő, Utolsó) vezérlő nyomógombokkal megjeleníthetők, illetve egyben, időzítve animációként is lejátszható a rajzolási folyamat. Az elkészült program működése megfigyelhető az ábrán:

Fibonacci-spirál Java program

A bejegyzéshez tartozó teljes forráskódot ILIAS e-learning tananyagban tesszük elérhetővé tanfolyamaink résztvevői számára.

A Java SE szoftverfejlesztő tanfolyamunkon, a szakmai modul Objektumorientált programozás témakörét követő 29-36. óra Grafikus felhasználói felület alkalmain már tudunk egyszerűbb szimulációs programot tervezni, kódolni, tesztelni.

Fibonacci nap

Fibonacci logó

Fibonacci logóA Fun Holidays – Fun, Wacky & Trivial Holidays weboldal sokféle különleges ünnepnapot listáz. Ezek leírása többnyire vicces, emlékezős, de néhány igazán érdekes, régi-régi hagyományt elevenít fel.

Ma van (november 23.) a Fibonacci nap. Fibonacci középkori matematikus volt, ő tette közismertté a Fibonacci-sorozat-ot. A (0), 1, 1, 2, 3, 5, 8, 13, 21, 34, sorozat igen népszerű azok közében is, akik programozást tanulnak. A sorozat első két eleme 1 és 1 (ha szükséges, akkor nulladik elemmel is dolgozhatunk), és minden további elem az előző két elem összege. Többféle történet is fűződik ehhez, talán az egyik legismertebb a nyúlpárok szaporodásához kötődik.

Honnan származik a Fibonacci nap? A mai nap hh.nn. formátumban 11.23. , és a számjegyek részei a Fibonacci-sorozatnak. Mindössze ennyi, ilyen egyszerű. 😉

A sorozat elemei könnyen előállíthatók néhány változó használatával, ha a kezdő programozó már ismeri a ciklust, mint algoritmikus építőelem – ez az iteratív megoldás. A rekurzív megoldás tipikus rossz megoldásként ismert, lássuk ennek Java megvalósítását:

Ha kiadnám a fenti Java forráskódot papíron ezt egy dolgozatban, zárthelyin, állásinterjú szakmai részén azzal a kérdéssel, hogy mit ír ki a program a képernyőre, akkor bizony sokan bajban lennének. Meg is történt ez már sokszor, tapasztalatból írom. A rekurzió első leszálló ágáig szinte mindenki eljut, de az ott induló első felszálló ágat követően sokan belezavarodnak a részlépések egymásutániságába. A végeredményt szinte mindenki tudja, de itt most arra helyezzük a hangsúlyt, hogy hogyan jutunk el odáig. Persze n=5-re fib(5)=5. Alig fordult még elő, hogy valaki hibátlanul leírta volna az alábbi eredményt:

A megoldás során – emlékeztetek arra, hogy ez atipikus megközelítés – sok-sok redundáns lépés történik. Hiszen például a fib(3)-at tudni kell a fib(4)-hez és a fib(5)-höz is, hiszen fib(4)=fib(2)+fib(3) és fib(5)=fib(3)+fib(4), valamint ebben az implementációban nincs semmilyen emlékezet (puffer, adatszerkezet), amivel a sok feleslegesnek vélhető számítást elkerülhetnénk.

Nyert ügye lehet annak, aki „fejben összerakja” az alábbi fát – akár dinamikusan, menet közben hozzáadva és törölve elemeket – és ebben navigálva (ezt bejárva) válaszolja meg a kérdést:

Fibonacci-sorozat-n=5

Az alábbi animáció segíthet a megértésben: 45 lépésben mutatja be az aktuális részlépést/részfeladatot (leszálló ág) és/vagy az aktuális részeredményt (felszálló ág):

Fibonacci-sorozat-n=5

A Fibonacci-sorozat többféleképpen kapcsolódik a természethez, természeti jelenséghez, növényekhez, állatokhoz (virágszirmok száma, levelek elfordulása, napraforgók magjai, fenyőtoboz pikkelyei, nautilus háza, aranymetszés, zenei hangolás, zeneművek tagolása), felhasználható algoritmusok futási idejének becsléséhez, fa adatszerkezetek építéséhez is. Az aranymetszésről megoszlanak a vélemények: vannak akik szinte mindenben ezt látják (művészet: festészet, szobrászat), mások módszeresen cáfolják ezt (például Falus Róbert: Az aranymetszés legendája, Magyar Könyvklub, 2001, második, javított kiadás, ISBN 963-547-332-X).

A bejegyzéshez tartozó teljes forráskódot ILIAS e-learning tananyagban tesszük elérhetővé tanfolyamaink résztvevői számára.

A feladat a Java SE szoftverfejlesztő tanfolyam szakmai moduljának 9-12. óra: Metódusok, rekurzió alkalmához kötődik.