ÚVODNÍ ZNALOSTI. datové struktury. správnost programů. analýza algoritmů



Podobné dokumenty
Úvod do programování - Java. Cvičení č.4

Algoritmizace a programování

5 Rekurze a zásobník. Rekurzivní volání metody

Úvod do programovacích jazyků (Java)

Základní pojmy. Úvod do programování. Základní pojmy. Zápis algoritmu. Výraz. Základní pojmy

Řídicí struktury. alg3 1

int t1, t2, t3, t4, t5, t6, t7, prumer; t1=sys.readint();... t7=sys.readint(); prume pru r = r = ( 1+t 1+t t3+ t3+ t4 t5+ t5+ +t7 +t7 )/ ;

3. přednáška. Obsah: Řídící struktury sekvence, if-else, switch, for, while, do-while. Zpracování posloupnosti

Paměť počítače. alg2 1

ABSTRAKTNÍ DATOVÉ TYPY (ADT)

KTE / ZPE Informační technologie

Složitost algoritmů. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

Výrazy a operátory. Operátory Unární - unární a unární + Např.: a +b

PODOBÁ SE JAZYKU C S NĚKTERÝMI OMEZENÍMI GLOBÁLNÍ PROMĚNNÉ. NSWI162: Sémantika programů 2

8 Třídy, objekty, metody, předávání argumentů metod

Časová složitost / Time complexity

Algoritmy I, složitost

Datové struktury. alg12 1

Test prvočíselnosti. Úkol: otestovat dané číslo N, zda je prvočíslem

11 VYPOČITATELNOST A VÝPOČTOVÁ SLOŽITOST

Logické operace. Datový typ bool. Relační operátory. Logické operátory. IAJCE Přednáška č. 3. může nabýt hodnot: o true o false

5 Přehled operátorů, příkazy, přetypování

Generické programování

9. přednáška - třídy, objekty

V případě jazyka Java bychom abstraktní datový typ Time reprezentující čas mohli definovat pomocí třídy takto:

Datové struktury. Obsah přednášky: Definice pojmů. Abstraktní datové typy a jejich implementace. Algoritmizace (Y36ALG), Šumperk - 12.

Programování v Javě I. Leden 2008

Programování v Javě I. Únor 2009

DTP Základy programování Úvod do předmětu

Složitost algoritmů. Karel Richta a kol. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze Karel Richta a kol.

Počítačové laboratoře bez tajemství aneb naučme se učit algoritmizaci a programování s využitím robotů CZ.1.07/1.3.12/

Časová složitost algoritmů

Tato tematika je zpracována v Záznamy přednášek: str

Algoritmizace. Jiří Vyskočil, Marko Genyg-Berezovskyj 2010

V každém kroku se a + b zmenší o min(a, b), tedy vždy alespoň o 1. Jestliže jsme na začátku dostali 2

Složitost 1.1 Opera ní a pam ová složitost 1.2 Opera ní složitost v pr rném, nejhorším a nejlepším p ípad 1.3 Asymptotická složitost

IAJCE Přednáška č. 8. double tprumer = (t1 + t2 + t3 + t4 + t5 + t6 + t7) / 7; Console.Write("\nPrumerna teplota je {0}", tprumer);

7 Formátovaný výstup, třídy, objekty, pole, chyby v programech

Výčtový typ strana 67

Rozklad problému na podproblémy

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

7. Datové typy v Javě

Seminář Java II p.1/43

Seminář z IVT Algoritmizace. Slovanské gymnázium Olomouc Tomáš Kühr

KTE / ZPE Informační technologie

KTE / ZPE Informační technologie

ŘÍKÁME, ŽE FUNKCE JE ČÁSTEČNĚ SPRÁVNÁ (PARTIALLY CORRECT), POKUD KDYŽ JE SPLNĚNA PRECONDITION

Různé algoritmy mají různou složitost

Algoritmizace a programování

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Seznamy a iterátory. Kolekce obecně. Rozhraní kolekce. Procházení kolekcí

Zápis programu v jazyce C#

EVROPSKÝ SOCIÁLNÍ FOND. Úvod do PHP PRAHA & EU INVESTUJEME DO VAŠÍ BUDOUCNOSTI

6. Příkazy a řídící struktury v Javě

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

Úvod do programovacích jazyků (Java)

Šablony, kontejnery a iterátory

IB015 Neimperativní programování. Časová složitost, Typové třídy, Moduly. Jiří Barnat Libor Škarvada

C# konzole Podíl dvou čísel, podmínka IF

Algoritmizace a programování

Pascal. Katedra aplikované kybernetiky. Ing. Miroslav Vavroušek. Verze 7

Objektově orientované programování

Proměnná. Datový typ. IAJCE Cvičení č. 3. Pojmenované místo v paměti sloužící pro uložení hodnoty.

Spojové struktury. Spojová struktura (linked structure):

1. Téma 12 - Textové soubory a výjimky

6 Příkazy řízení toku

Matematická indukce a správnost programů. Základy diskrétní matematiky, BI-ZDM ZS 2011/12, Lekce 13

Dynamické datové struktury III.

Ukazatel (Pointer) jako datový typ - proměnné jsou umístěny v paměti na určitém místě (adrese) a zabírají určitý prostor (počet bytů), který je daný

for (i = 0, j = 5; i < 10; i++) { // tělo cyklu }

Algoritmizace a programování. Terminálový vstup a výstup

Programování v C++, 2. cvičení

IAJCE Přednáška č. 9. int[] pole = new int[pocet] int max = pole[0]; int id; for(int i =1; i< pole.length; i++) { // nikoli 0 if (Pole[i] > max) {

DSA, První krok: máme dokázat, že pro left = right vrátí volání f(array, elem, left, right)

8. přednáška: Soubory a proudy

Mimo samotné správnosti výsledku vypočteného zapsaným algoritmem je ještě jedno

Martin Hejtmánek hejtmmar

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Rekurze a zásobník. Jak se vypočítá rekurzivní program? volání metody. vyšší adresy. main(){... fa(); //push ret1... } ret1

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 21.

VZOR. Vzor přijímacího testu do magisterského studia oboru Otevřená informatika

Obsah přednášky. Příkaz for neúplný. Příkaz for příklady. Cyklus for each (enhanced for loop) Příkaz for příklady

Algoritmizace prostorových úloh

Abstraktní datové typy: zásobník

Stručný návod k programu Octave

7. přednáška - třídy, objekty třídy objekty atributy tříd metody tříd

10. Složitost a výkon

Datové typy v Javě. Tomáš Pitner, upravil Marek Šabo

Příkazy a řídicí struktury v Javě. Tomáš Pitner, upravil Marek Šabo

Středoškolská technika 2017 PROGRAM NA GENEROVÁNÍ PRVOČÍSEL

Základy programování (IZP)

Programové konvence, dokumentace a ladění. Programování II 2. přednáška Alena Buchalcevová

PŘETĚŽOVÁNÍ OPERÁTORŮ

PREPROCESOR POKRAČOVÁNÍ

Programovací jazyk Pascal

Objekty, třídy, instance

Generování vnitřní reprezentace programu

Dynamické datové struktury IV.

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 12.

Transkript:

ÚVODNÍ ZNALOSTI datové struktury správnost programů analýza algoritmů

Datové struktury základní, primitivní, jednoduché datové typy: int, char,... hodnoty: celá čísla, znaky, jednoduché proměnné: int i; char c; obsahují hodnoty třídy: class Auto {, class Bod{,... hodnoty: objekty, instance třídy new Auto(), referenční proměnné: Auto a; Bod b; obsahují ukazatele na objekty a ukazatel null

Poznámka: pole: T[ ] hodnoty: objekty, n-tice proměnných typu T, new T[n] proměnné: T[ ]v; obsahují ukazatele na objekty a ukazatel null datová struktura schéma uložení souvisejících hodnot, objektů - sekvenční datová struktura - spojová datová struktura

ZOO druhy zvířat třída DruhZvirat class DruhZvirat { String druh; int pocet; // jmeno druhu zvirat // pocet zvirat DruhZvirat (String druh, int pocet) { this.druh = druh; this.pocet = pocet; void tisk() { System.out.println(druh+" " +pocet);

Sekvenční implementace pole z - pole druhů zvířat v ZOO = pole objektů třídy DruhZvirat DruhZvirat[] z = new DruhZvirat[4]; // uděláme si malou, ale naši ZOO // nejvíce 4 čtyři druhy zvířat // pocet počet druhů zvířat // budeme mít // 4 opice, 2 slony, 4 žirafy

class PoleZvirat { public static void main(string[] args){ DruhZvirat[] z = new DruhZvirat[4]; int pocet = 0; //pocet druhu zvirat tisk(z,pocet); z[pocet] = new DruhZvirat("opice",4); pocet++; tisk(z,pocet); z[pocet] = new DruhZvirat("sloni",2); pocet++; tisk(z,pocet); z[pocet] = new DruhZvirat("zirafy",4); pocet++; tisk(z,pocet); static void tisk(druhzvirat[] z, int pocet) { int i = 1; while(i <= pocet) { z[i-1].tisk(); i++;

datová struktura je dobře co není dobře? data ZOO DruhZvirat[] z; int pocet; jakož i operace nad nimi jsou oddělené! třída ZOO :-)

class ZOO { DruhZvirat[] z; int pocet; ZOO() { z = new DruhZvirat[4]; pocet = 0; void pridej (String druh, int kolik) { z[pocet] = new DruhZvirat(druh, kolik); pocet++; void tisk() { int i = 1; while(i <= pocet) { z[i-1].tisk(); i++;

vytvoříme objekt(y) třídy ZOO class ZOOHlavni { public static void main(string[] args){ ZOO plzen = new ZOO(); plzen.pridej("opice",4); plzen.tisk(); plzen.pridej("sloni",2); plzen.tisk(); plzen.pridej("zirafy",4); plzen.tisk();

Spojové datové struktury zacatek dalsi obecně data obsahují ukazatel, pointer, referenci, odkaz, směrník,... na další data Java třída obsahuje referenční proměnnou dalsi

class DruhZvirat { String druh; int pocet; DruhZvirat dalsi; DruhZvirat (String druh, int pocet) { this.druh = druh; this.pocet = pocet; // dalsi bude inicalizovano na null void tisk() { System.out.println(druh+" "+pocet);

// nasledující program je ilustrací spojování objektů // z zvířata jejich začátek z dalsi posledni

class SeznamZvirat { public static void main(string[] args){ DruhZvirat z = null; //zacatek DruhZvirat posledni; tisk(z); DruhZvirat novydruh; novydruh = new DruhZvirat("opice",4); z = novydruh; posledni = novydruh; tisk(z); novydruh = new DruhZvirat("sloni",2); posledni.dalsi = novydruh; posledni = novydruh; tisk(z); novydruh = new DruhZvirat("zirafy",4); posledni.dalsi = novydruh; posledni = novydruh; tisk(z); static void tisk(druhzvirat z) { DruhZvirat x = z; while (x!= null) { x.tisk(); x = x.dalsi;

datová struktura dobře, ale... - třída ZOO class ZOO { DruhZvirat z; //zacatek seznamu zvirat DruhZvirat posledni; ZOO() { z = null; void pridej (String druh, int kolik) { DruhZvirat novydruh; novydruh = new DruhZvirat(druh,kolik); if (z == null) z = novydruh; else posledni.dalsi = novydruh; posledni = novydruh; void tisk() { DruhZvirat x = z; while (x!= null) { x.tisk(); x = x.dalsi;

klient ZOOHlavni třídy ZOO je stejný obě implementace třídy ZOO poskytují stejné metody a klient používá pouze tyto metody

Obecnější spojová datová struktura... Řád plemenné knihy arabského koně 7.2. Plemenná kniha se člení: - plemenná kniha hřebců - plemenná kniha klisen... 14.6. Pojmenovávání koní. Plemenní hřebci - dnem platnosti PK obdrží každý hřebec nově zapsaný do PK jméno, které má stejné začáteční písmeno jako linie k níž po otci přísluší.... Plemenné klisny - pojmenování klisen je libovolné a přísluší chovateli s požadavkem zabránění duplicity.

class Hrebec { String jmeno; Hrebec nejmladsisyn; Hrebec starsibratr; Hrebec (String jmeno) { this.jmeno = jmeno; String getjmeno( ) { return jmeno;

nejmladsisyn starsibratr

class Linie { Hrebec zakladatel; Linie(String jmeno) { zakladatel = new Hrebec(jmeno); void pridejsyna(hrebec otec, String jmeno) { Hrebec novy = new Hrebec(jmeno); novy.starsibratr = otec.nejmladsisyn; otec.nejmladsisyn = novy;

class HrebciHlavni { /* toto je pouze ilustrace obecnejsi spojove struktury */ public static void main(string[] args) { Linie linieb = new Linie ("Bosbar"); System.out.println("\n"+"zakladatelem linie je "+ linieb.zakladatel.getjmeno()+"\n"); linieb.pridejsyna(linieb.zakladatel, "Borax"); linieb.pridejsyna(linieb.zakladatel, "Bertik"); System.out.println("nejmladsi syn je "+ linieb.zakladatel.nejmladsisyn.getjmeno()+"\n"); System.out.println("druhy nejmladsi syn je "+ linieb.zakladatel.nejmladsisyn.starsibratr.getjmeno() +"\n"); linieb.pridejsyna (linieb.zakladatel.nejmladsisyn.starsibratr, "Brist"+"\n"); System.out.println("(nejmladsi) syn Boraxe je "+ linieb.zakladatel.nejmladsisyn.starsibratr.nejmladsisyn. getjmeno()+"\n"); http://www.kiv.zcu.cz/~netrvalo/vyuka/ppa2/portal/cviceni/cv03.pdf

Správnost programů Testováním programu, tj. ověřením, že pro daný vstup získáme správný výstup nemůžeme obecně prokázat správnost programu. Testování může prokázat chybu v programu.

Programová logika ne hodnoty vstupu a výstupu vztah mezi hodnotami (relevantmích) proměnných před a po vykonání příkazu tvrzení, logický výraz ( x 0 před dělením x) tvrzení před příkazem předpoklad (precondition) tvrzení před příkazem důsledek (postcondition) {předpoklad příkaz; {důsledek {P příkaz; {Q

posloupnost příkazů příkaz1; příkaz2; {předpoklad1 příkaz1; {důsledek1 důsledek1 předpoklad2 (implikuje) předpoklad2 příkaz2; důsledek2 předpoklad1 příkaz1; příkaz2; důsledek2

přiřazení {Q(e) v = e; // proměnné v přiřadí hodnotu výrazu e {Q(v) // vstup x x = x 1; y = sqrt(x+2); // může být x 0, důsledek příkazu vstupu? {x -1 x = x 1; // x 1-2 {x -2 {x -2 y = sqrt(x+2); // (x+2) 0 {y 0 x 0 x -1

alternativa {P if B S1; else S2; {Q musí být: {P && B {P &&!B S1; S2; {Q {Q { true if ( x >= y ) // B m = x; // S1 else m = y; // S2 {(x >= y && m ==x) (x<y) && m==y) //maximum

pro S1 musí být { x>=y m = x; {(x >= y && m ==x) (x<y) && m==y) je {(x >= y && x ==x) (x<y) && x==y) m = x; {(x >= y && m ==x) (x<y) && m==y) protože (x>=y) (x >= y && x ==x) (x<y) && x==y) skutečně je { x>=y m = x; {(x >= y && m ==x) (x<y) && m==y) podobně pro S2

cyklus řazení vkládáním int a[ ] = new int [n]; for (int j=1; j < a.length; j++) { int vkladanahodnota = a[j]; // (n-1)-krát int i = j; while (i > 0 && a[i-1] > vkladanahodnota) { // pro každé j=1,,n-1obecně k j -krát a[i] = a[i-1]; --i; a[i] = vkladanahodnota; na začátku každého vykonávání cyklu for, začátek pole s prvky s indexy 0... j-1 obsahuje hodnoty původních prvků, jenomže seřazené tuto vlastnost nazýváme invariantem cyklu

tři vlastnosti invariantu cyklu Inicializace: Je splněn před vykonáním prvního cyklu. Udržování: Je-li splněn pře vykonáním cyklu, zůstává splněn i po něm. Skončení: Když cyklus skončí, invariant nám ukáže správnost algoritmu. (Obdoba matematické indukce, kromě skončení.) řazení vkládáním Inicializace: Po začátečním přiřazení j = 1 je pole s prvky s indexy 0... j-1 triviálně seřazeno. Udržování: Cyklus for posouvá prvky a[j-1],a[j-2],... o jednu pozici doprava dokud se nenajde správné místo pro a[j]. Skončení: Cyklus for skončí když j=n, kde n je počet prvků pole. Dosazením do textu invariantu cyklu dostáváme, že prvky s indexy 0... n-1 obsahují seřazené původní prvky pole.

jenom teorie? ne příkaz assert assert výraz1 : výraz2 ; výraz1 tvrzení, logický výraz výraz2 chybová zpráva // použijte -ea v příkazu java import java.util.scanner; public class Assert { public static void main( String args[] ) { Scanner input = new Scanner( System.in ); System.out.print( "Zadejte cislo mezi 0 a 10: "); int cislo = input.nextint(); // tvrdime, ze cislo musi byt >= 0 a <= 10 assert ( cislo >= 0 && cislo <= 10 ) : "Chybne cislo: " + cislo; System.out.printf( "Zadali jste %d\n", cislo );

Analýza algoritmů Analýza algoritmu určuje požadované prostředky na jeho vykonání. Nejčastěji nás zajímá čas výpočtu Označme c operace počet elementárních kroků potřebných pro vykonání určité operace Je-li vykonána n-násobně, přispěje k času vykonání n*c operace

Splnitelnost výrokových formulí if (booleovský výraz) příkaz; Nechť booleovský výraz pozůstává z - n proměnných logického typu v1, v2,, vn - m logických operátorů not, and, - závorek c h - čas přiřazení hodnoty proměnné c o - čas každé logické operace vyhodnocení podmínky (výrokové formuly) T(n,m) = n c h + m c o Výroková formule (podmínka) je splnitelná existuje-li přirazení hodnot true a false proměnným v1, v2,, vn takové, že hodnota formule (logického výrazu) je true.

Úkol zjistit zda-li je zadaná formule splnitelná Algoritmus pro každé možné přiřazení hodnot proměnným v1, v2,, vn formuli vyhodnoť Počet různých přiřazení je 2 n a čas výpočtu algoritmu je T(n,m) = 2 n (n c h + m c o)

Násobení matic int[ ][ ] a = new int[n][n]; int[ ][ ] b = new int[n][n]; int[ ][ ] c = new int[n][n]; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { c[i][j] = 0; for (int k = 0; k < n; k++) c[i][j] = c[i][j] + a[i][k]*b[k][j]; Čas výpočtu: n-krát vnější cyklus ( n-krát cyklus pro j ( c nulování + n-krát vnitřní cyklus ( c sčítání + c násobení ))) T(n)=n 2 (c nulování + n( c sčítání + c násobení )) = n 3 ( c sčítání + c násobení ) + n 2 c nulování = an 3 + bn 2

Co z an 3 + bn 2 dostatečně charakterizuje chování algoritmu, tedy míru růstu času výpočtu v závislosti na velikosti problému n? Důležité je chování pro velká n. Pro a=b=1 a n=1000 je celková hodnota uvedeného výrazu 1 001 000 000 a člen n 2 (1 000 000) přispívá podílem 0,1%. n 3 tedy intuitivně charakterizuje růst času výpočtu algoritmu v závislosti na velikosti vstupu.

Řazení vkládáním int a[ ] = new int [n]; for (int j=1; j < a.length; j++) { int vkladanahodnota = a[j]; // (n-1)-krát int i = j; while (i > 0 && a[i-1] > vkladanahodnota) { // pro každé j=1,,n-1 obecně k j -krát a[i] = a[i-1]; --i; a[i] = vkladanahodnota; čas výpočtu n-1 n-1 T(n)=3(n-1)*c přiř + c por k j + 2c přiř (k j -1) j=1 j=1 Pozn.: k j závisí na zadané řazené posloupnosti může být různé pro totéž j

v nejlepším případě k j = 1 a T(n)=(n-1)*(3c přiř + c por ) - růst času výpočtu je lineární - n v nejhorším případě k j = j+1 a T(n)=3(n-1)*c přiř + (n(n+1)/2-1)c por + n(n-1)c přiř - růst času výpočtu je kvadratický n 2 v průměrném případě k j = (j+1)/2 a - růst času výpočtu je opět kvadratický n 2 Časová složitost - růst času výpočtu v nejhorším nebo průměrném případě

Asymptotická složitost Asymptotická složitost vyjadřuje limitní růst času výpočtu, když velikost problému neomezeně roste. Funkce g(n) je Θ(f(n)) existují-li kladné konstanty c 1, c 2 a n 0 takové, že pro všechna n n 0 0 c 1 f(n) g(n) c 2 f(n) Růst času výpočtu uvedeného algoritmu násobení matic jsme intuitivně navrhli charakterizovat členem n 3 Čas výpočtu uvedeného algoritmu je Θ(n 3 ) c 1 n 3 an 3 + bn 2 c 2 n 3 a,b > 0 c 1 a + b/n c 2 c 1 = a, c 2 = a + b/ n 0, n 0 libovolné kladné Polynom a d n d + + a 0, a d >0 je Θ(n d ) Θ notace omezuje funkci shora i zdola

Asymptotické omezení shora Funkce g(n) je O(f(n)), existují-li kladné konstanty c a n 0 takové, že pro všechna n n 0 0 g(n) cf(n) an 3 + bn 2 je tedy O(n 3 ), ale i O(n 4 ), Pro algoritmus řazení vkládáním: - nejhorší případ O(n 2 ) - každý vstup O(n 2 ) - nejlepší případ je O(n)

Asymptotické omezení zdola Funkce g(n) je Ω(f(n)), existují-li kladné konstanty c a n 0 takové, že pro všechna n n 0 0 cf(n) g(n) Pro algoritmus řazení vkládáním: -nejlepší případ Ω(n) -pro každý vstup Ω(n) -nejhorší případ Ω(n 2 )

Rychlost procesoru Předpokládejme, že rychlost procesoru se zvětšila k-krát. Byl-li za čas T algoritmem s časem výpočtu f(n) vyřešen problém o velikosti a na pomalejším procesoru, jak velký problém x vyřešíme stejným algoritmem na k-krát rychlejším počítači za stejný čas? Pro pomalejší počítač T=f(a) Pro rychlejší počítač T=f(x) Pro pomalejší počítač kt=f(x) x = f -1 (kt) = f -1 (k.f(a)) http://www.kiv.zcu.cz/~netrvalo/vyuka/ppa2/portal/cviceni/slozitost.pdf