Bevezetés Dr. Iványi Péter
Programozási készség Számos munka igényel valamilyen szintű programozási készséget Grafikus a képfeldolgozót, Zenész a szintetizátort, Programozó a számítógépet programozza. Nem csak készség, hanem szórakozás, illetve lehetőség a kreativitásra
Mit tanulhatunk? Kritikus olvasás Analitikus gondolkodás Kreatív szintézis Részletekre való odafigyelés Szinte mindenkinek meg kell tanulnia programozni!!!
A programozás lépései 1. Probléma leírása és adat definíció 2. A program viselkedésének informális leírása 3. A viselkedés bemutatása példákkal 4. A program általános szerkezetének, elrendezésének megtervezése 5. A konkrét program elkészítése 6. Tesztelés, hibakeresés és a részletek javítása * Dokumentáció készítés (felhasználói, fejlesztői)
A programozás lépései
Példa: Probléma megfogalmazása A 35 Celziusz fok hány Fahreinheit fok? A számítógép nem ért magyarul, így nekünk kell megtanulni a számítógép nyelvét, hogy utasításokat tudjunk adni neki. A számítógép nyelve a programozási nyelv (Az USA-ban a programok jogilag elfogadott emberi kifejezési formák! A szólásszabadság részei.)
Programkészítés A programozási nyelvek nagyon primitívek, a nyelvtanuk nagyon korlátozott Ráadásul a számítógépek is primitívek, mert csak azt csinálják amit mondunk nekik A legkisebb hiba a programban fatális hibát okozhat és nem a kívánt számítást végzi el A programozást gyakorolni kell Ezt fogjuk csinálni a félév során!!!
Szintaktika Programozási nyelv A forma, a reprezentáció Szemantika Az értelme, a koncepciója annak amit reprezentál Szintaktika Programozás I. Szemantika Problémaosztályok és algoritmusok
Bábel tornya
Programozási nyelvek Alacsony szintű: Gépközeli, közvetlenül a processzor utasításkészletére épül Gépi kód: A memóriában lévő utasításkódokat közvetlenül a programozó adja meg. Assembly: A közvetlen kódok helyett rövid, könnyen megjegyezhető szavakat alkalmazunk a könnyebb megjegyzés, a jobb átláthatóság kedvéért. Jobban áttekinthető címzési módok, megjegyzések lehetősége, külön fordítható egységek, teszik könnyebbé a még mindig a gép közvetlen utasításkészletére épülő programozást.
Programozási nyelvek Magasszintű: Cél a jobban áttekinthető minél egyszerűbb, gyorsabb programozás, mely érdekében kompromisszumot kell kötni a futássebesség és a tárfoglalás kárára.
Programozási nyelvek
Programozási nyelvek osztályozása Procedurális nyelvek Kifejezések sorozatát hajtjuk végre mely valamilyen eredményhez vezet Változókat, ciklusokat használunk Program állapotok Funkcionális nyelvek Nem igazán használunk tárolt állapotokat Nem ciklusokat hanem rekurziót használunk Függvényeket hívunk és a visszatérési értékeket használunk Változók módosítása mellékhatás!
Programozási nyelvek osztályozása Objektum-orientált nyelvek Minden egy objektum Script nyelvek Általában interpretált, egyszerű elkezdeni, de könnyű elrontani Lehet procedurális, objektum-orientált, stb. Logikai nyelvek Deklaratív kijelentéseket teszünk és a program meghatározza a konzekvenciákat
Programozási nyelvek osztályozása Nem igazán osztályok, inkább Programozási stílusok Programozási módszerek, technikák Például: C-ben is lehet objektum orientált módon programozni
Még egy osztályozás Statikus nyelvek (compiler-linker) A fordító program a forrásprogramot gépi kódra fordítja és így a program futtatásához se a forráskód se a fordító nem kell. C, C++, Fortran, Common LISP Dinamikus nyelvek (interpreter) Az értelmező program a forrásprogramot utasításként értelmezi és hajtja végre. LISP, Scheme Just-In-Time (JIT) fordító Java, Python, Scheme
Programozási nyelvek másként
Programozási nyelv generációk Generation Language (generáció) 1GL: gépi kód 2GL: assembly (mnemonic) 3GL: magasszintű procedurális FORTRAN, PASCAL, C 4GL: probléma orientált Funkcionális: LISP Logikai: PROLOG Adatbázis kezelés: SQL Objektum-orientált: C++, JAVA 5GL: természetes nyelvek
Elméleti kérdések
Halting probléma Egyik legfontosabb és legérdekesebb probléma, hogy mit lehet és mit nem lehet kiszámolni számítógéppel? Például mikor fog a program a végtelenségig futni? Megáll-e a program? Hogyan lehet eldönteni ezt a kérdést? Például lefuttajuk a kódot. De mi lesz ha sokáig fut? Meddig várjunk?
Halting probléma Tegyük fel hogy van megoldás, van olyan program mely eldönti, hogy egy program leáll-e. LEALL_E(PROGRAM, BEMENET) Argumentumok: PROGRAM : a vizsgálni kívánt program BEMENET : a vizsgálni kívánt program bemenete Visszatérési érték: Igaz: ha a PROGRAM leáll az adott bemeneti adattal Hamis: ha a PROGRAM örökké fut
Halting probléma Mire alkalmas a LEALL_E program: Egy sokáig futó programot megnézünk hogy megáll-e Ellenőrizhetjük, hogy a program teljesíti-e a teszteket?
Halting probléma Mi van ha olyan programot akarunk írni, mely megállapítja önmagáról hogy mi történik ha a program bemenete önmaga? SAJAT_MAGATOL_LEALL(program) { if(leall_e(program, program)) végtelen futás else halt }
Halting probléma SAJAT_MAGATOL_LEALL(program) Ha a program bemenete saját maga és így futtatnánk le és leállna akkor végtelen ideig fut. Ha a program saját magával mint bemenettel nem állna le akkor ez a program leáll
Halting probléma Ez nagyon jó, mert használhatjuk arra, hogy megnézzük hogy a LEALL_E program véget ér-e ha saját mágra futtatjuk le. És mi van ha a SAJAT_MAGATOL_LEALL programot saját magára futtatjuk le?
Halting probléma Ha igaz, hogy: LEALL_E(SAJAT_MAGATOL_LEALL, SAJAT_MAGATOL_LEALL ) akkor: SAJAT_MAGATOL_LEALL(SAJAT_MAGATOL_LEALL) végtelen ideig fut. Ellentmondáshoz vezet!!! Ha igaz, hogy leáll saját magától akkor végtelen ideig fut.
Halting probléma Tehát fordítva kell hogy legyen, hamis az: LEALL_E(SAJAT_MAGATOL_LEALL, SAJAT_MAGATOL_LEALL ) és így: SAJAT_MAGATOL_LEALL(SAJAT_MAGATOL_LEALL) tehát ha nem áll le saját magától akkor végtelen ideig fut, ami szintén ellentmondás!!! Hol a probléma?
Hol a probléma? Halting probléma A SAJAT_MAGATOL_LEALL program teljesen érvényes kód, minden szabályos benne A gyanús rész a: LEALL_E program Következmény: A leállási (halting) probléma, ahogy itt leírtuk, általános esetben nem oldható meg! Nem létezik LEALL_E program!
Halting probléma Segít-e ez a megállapítás rajtunk? Nem lehet olyan programot írni, mely megállapítja egy programról, hogy az a saját bináris kódját írja-e ki. Így a vírusok detektálása elméletileg eldönthetetlen kérdés. Bizonyos esetekben persze lehet bizonyítani a megállást, de a lényeg, hogy nincs általános módszer. Például: Ha valaki tudja a szorzótáblát 1-10 ig az nem jelenti ugyanazt, hogy bármely két számot össze tud szorozni.
Halting probléma Gyakorlati következmény: A program jósága, működőképessége így intuitív fogalom. Megállapodás szerint tehát akkor nevezünk jónak egy programot, ha az mindenben a specifikációjának megfelelően működik.
Hatékonyság Számítástechnikában sokszor nem az a kérdés hogy hogyan oldjunk meg valamit, hanem az hogy hogyan lehet jól megoldani. Például: Szavak ábécé sorrendbe rendezése Próbálgatás (Brute force) 100 szó esetén 100! (100 faktoriális) lehetőség van (158 jegyű szám) Ha 1,000,000,000 próbát 1 másodperc alatt lehet elvégezni még mindig 10 149 másodperc kell!!!
Hatékonyság n szó rendezésénél n! műveletre van szükség Ha már valamennyire rendezettek a szavak akkor az átlagos hatékonyság n!/2 de ez is csak kis mértékben csökkenti a műveletek számát így a konstansokat nem szoktuk figyelembe venni
Hatékonyság Egy probléma megoldására többféle algoritmus írható Hogyan válasszunk: Az algoritmus elkészítésének bonyolultsága Az algoritmus futási ideje Az algoritmus által használt memória alapján
Hatékonyság A legtöbb algoritmusnak n bemenete van és a bemenet méretének közvetlen hatása van az algoritmus futási és memória igényére Algoritmusok analízise Meghatározni az algoritmus erőforrás igényét n függvényében ahol n egy nagy szám
Order bonyolultság Nagy O jelölés Például: O(n!) Hatékonyság Csak a nagy képet nézzük, a kis részletek elhanyagolásával
Nagy O jelölés A konstansokat elhanyagoljuk: 2n 3 = O(n 3 ) Alacsonyabb fokú tényezőket szintén elhagyjuk: n 3 +n 2 = O(n 3 ) ha n > 1, n 2 < n 3 így n 3 +n 2 < 2n 3 = O(n 3 ) A logaritmus kitőve sem számít: log x N = O(log y N) minden x,y > 1 esetén
Nagy O jelölés O(1) : konstans O(log N) : logaritmikus O(N) : lineáris O(N log N) : log-lineáris O(N k ) : polinomiális O(k N ) : exponenciális
Polinomiális Nagy O jelölés O(1) mindegy, hogy mi a bemenet O(n) a bemeneti adatokon csak egyszer kell keresztul menni O(n log n) általában a jó rendező algoritmusok O(n 2 ) kiválasztásos rendező algoritmus Nem polinomiális O(2 n ) -
Végrehajtási idő t(n) n=10 n=20 n=30 n=40 n=50 n=60 n 0.00001 mp 0.00003 mp 0.00003 mp 0.00004 mp 0.00005 mp 0.00006 mp n 2 0.0001 mp 0.0004 mp 0.0009 mp 0.0016 mp 0.0025 mp 0.0036 mp n 3 0.001 mp 0.008 mp 0.027 mp 0.064 mp 0.125 mp 0.256 mp n 5 0.1 mp 3.2 mp 24.3 mp 1.7 perc 5.2 perc 13.0 perc 2 n 0.001 mp 1.0 mp 17.9 perc 12.7 nap 35.7 év 366 évszd 3 n 0.059 mp 58 perc 6.5 év 3855 évszd 2e8 évszd 1.3e13 évszd Számítógép, mely másodpercenként 1 millió műveletet hajt végre. n a bemenet mérete.
Végrehajtási idő Ha probléma az NP kategóriába tartozik, akkor a gyorsabb számítógép sem segít Hogyan változik a futási idő: t(n) Mai gép 100-szor gyorsabb 1000-szer gyorsabb n N 1 100 N 1 1000 N 1 n 2 N 2 10 N 2 31.6 N 2 n 3 N 3 4.64 N 3 10 N 3 n 5 N 4 2.5 N 4 3.98 N 4 2 n N 5 N 5 + 6.64 N 5 + 9.97 3 n N 6 N 6 +4.19 N 6 + 6.29 kis gyorsulás!!!
Memória Eddig feltételeztük, hogy a számítógépnek mindig van elég memóriája Hely komplexitás is meghatározó az algoritmusoknál Verem (Stack) mérete rekurzív algoritmusoknál Lapozás operációs rendszereknél
Memória A memóra elérési idő is fontos lehet Mai rendszerek cache -t használnak Fontos az adatok elhelyezkedése, vagyis hogy mindig rendelkezésre álljon az algoritmus számára
Bonyolultság elmélet Általában nem kívánatos ha bizonyítjuk, hogy egy probléma nem oldható meg, De a kriptográfiában éppen ezt használjuk ki. Faktorizálás
NP teljesség Az általunk vizsgált algoritmusok polinomiális idejűek, azaz n méretű bemenet esetén a futási idejük a legrosszab esetben is O(n k ). Vajon minden probléma megolható-e polinomiális időben? Válasz: nem Például: megállási probléma P = NP sejtés, hogy az NP-teljes problémák nem oldhatók meg polinomiális idő alatt
NP teljesség Ha csak egy NP problémáról bebizonyítják, hogy megoldható polinomiális időben akkor az összes megoldható lesz, mivel mindegyik NP-teljes probléma visszavezethető egy NP teljes feladatra. Például a Hamilton kör meghatározásra Boole-hálózatok kielégíthetősége Kriptográfia, titkosítás a P = NP sejtést használja
Boole-hálózatok kielégíthetősége Circuit-satisfiability, C-SAT Vegyünk egy Boole hálózatot A bemeneti Boole változóknak lehet-e olyan értéket adni, hogy a hálózat kimenete egy (igaz) legyen
Boole-hálózatok kielégíthetősége x 1 1 1 x VAGY 2 1 1 VAGY NEM 0 VAGY 1 1 ÉS x 3 0 1 NEM ÉS
Bonyolultság elmélet A nagy O jelölés egy felső korlátot ad meg Az jelölés egy alsó korlátot ad meg A jelölés egy alsó és felső korlátot ad meg
Szoftver projektek
IBM 360 Első általános célú operációs rendszer 1964 Több módszer helyességét is bizonyította a project: Frederick Brooks: The Mythical Man-Month, Addison- Wesley Professional, 1995 370-es sorozat és zseries is innen származtatható Még mindig kompatibilisek visszafelé
Apolló irányító rendszere MIT Instrumentation Lab 1969 Apollo 11 holdra szállásánál használták Raytheon computer 8 Kbyte memória
Híres projektek Mosaic az első Web browser Deep Blue sakk automata VisiCalc első táblázatkezelő UNIX operációs rendszer...
Félresikerült projektek 1. BAE Automated Systems Denver International Airport Csomagok kezelésére fejlesztett szoftver 1993 október Annyit hibázott, hogy csak 16 hónappal később nyittot meg a reptér Veszteség: 1.1 millió dollár naponta
Félresikerült projektek 2. Federal Aviation Administration, USA Háromszor próbáltak készítettni egy repülőirányitási rendszert Háromszor több száz millió dollár