Pobierz Informatyka od wielomianów - Notatki - Informatyka - Część 1 i więcej Notatki w PDF z Informatyka tylko na Docsity! Wyznaczanie wartości wielomianu Zadanie: Wyznaczyć wartość wielomianu a0+a1 ∗x+a2 ∗x2+···+an ∗xn w punkcie x = x0. ⋆ Podejście naiwne: a0+a1 ∗x0+a2 ∗x0 ∗x0+···+an ∗x|0 ∗·{·z·∗x}0 nrazy Liczba mnożeń = 0+1+···+n = n(n+1) 2 = 1 2n2+ 12 n Liczba dodawań = n Złożoność O(n2) ⋆ Schemat Hornera: ((. . . (an ∗x0+an−1) ∗x0 . . .) ∗x0+a1) ∗x0+a0 Liczba mnożeń = n Liczba dodawań = n Złożoność O(n) Wyznaczanie reprezentacji dziesiętnej liczby Zadanie: Liczbę zapisaną w systemie o bazie b jako cncn−1 . . .c1c0 przedstawić w postaci dziesiętnej. Rozwiązanie: Dokładnie tak samo jak przy wyznaczaniu wartości wielomianu, bo szukana liczba to c0+c1 ∗b+c2 ∗b2+···+cn ∗bn. Liczymy więc wg schematu Hornera: ((. . . (cn ∗b+cn−1) ∗b. . .) ∗b+c1) ∗b+c0. Mnożenie dwóch liczb całkowitych ⋆ przez sumowanie: m∗n = m| +·{·z·+m} n razy Liczba dodawań = n−1 Złożoność O(n) ⋆ mnożenie pisemne: Warunek: znajomość tabliczki mnożenia (mnożenie jednocyfrowe). Liczba cyfr w liczbie n ≈ log10 n Liczba mnożeń liczb jednocyfrowych = logm∗logn Liczba dodawań = logm∗logn−1 Złożoność O(logm∗logn) Rozwiązywanie równań kwadratowych Zadanie: Rozwiązać równanie ax2+bx+c = 0. Rozwiązanie: docsity.com = b2−4ac, x1/2 = −b±√ 2a , o ile > 0. Liczenie : 4 operacje podstawowe Liczenie x1/2: 5 operacji (w tym 1 pierwiastkowanie) Złożoność O(1) – liczba operacji nie zależy od danych wejściowych. Sito Eratostenesa Zadanie: Wyznaczyć liczby pierwsze nie większe niż n ∈ N. ⋆ Algorytm naiwny: sprawdzamy po kolei liczby i oceniamy czy są pierwsze. Koszt sprawdzenia czy liczba k ∈ N jest pierwsza, gdy sprawdzamy po kolei wszystkie potencjalne dzielniki od 2 do √k: O(k 1 2 ) = O(√k). Łączny koszt ≈ √2+√3+···+√n. ⋆ Sito Eratostenesa: ◮ Ze zbioru wartości {k ∈ N;2 6 k 6 n} „wykreślamy” z niego liczby, które nie są pierwsze w następujący sposób: bierzemy po kolei liczby od najmniejszej do największej i jeśli wybrana liczba nie jest wykreślona, to wykreślamy wszystkie jej wielokrotności. ◮ Liczby pierwsze pozostają nie wykreślone. ◮ Uwaga: Wykreślanie wielokrotności k można zacząć od k2, bo wszystkie wcześniejsze wielokrotności zostały już wcześniej wykreślone. Złożoność pamięciowa: O(n). Złożoność czasowa: O(nlognloglogn). Języki programowania ⋆ różne podejścia = różne oczekiwania ⋆ różne poziomy abstrakcji ◮ niski poziom – blisko instrukcjom procesora 1 AND AX, 00FFH 2 MOV CL, 12 3 SHR BX, CL 4 SHL AL, CL 5 NEG CL ◮ wysoki poziom – blisko językowi naturalnemu 1 WydrukujOryginał; 2 if liczbaKopii > 0 then 3 for i := 1 to liczbaKopii do 4 WydrukujKopi ˛e; ⋆ meta-kod – nie konkretny język a precyzyjne wyrażenia niemal w języku naturalnym Języki imperatywne i deklaratywne ⋆ kompletnie różne sposoby myślenia docsity.com Obrazy rekurencyjne – fraktale Dwa proste przykłady: dywan i trójkąt Sierpińskiego Rekurencja w programowaniu Silnia rekurencyjnie 1 function Silnia(n : integer) : longint 2 begin 3 if n < 2 then 4 Silnia := 1; 5 else 6 Silnia := n ∗ Silnia(n−1); 7 end Stos wywołań funkcji ⋆ Przy wywołaniu funkcji wewnątrz innej funkcji należy zapamiętać stan tej przerywanej, by przejść do wykonywania tej wywołanej. ⋆ Uwaga na nieskończone wywołania – powodują przepełnienie stosu. ⋆ Obsługa stosu kosztuje - zarówno czasowo jak i pamięciowo. ⋆ Optymalnie napisane funkcje nierekurencyjne są zawsze szybsze niż rekurencyjne. ⋆ Kiedy stosować rekurencję? Gdy spełnione są dwa warunki: ◮ natura problemu jest rekurencyjna (wtedy czytelność kodu jest bardzo dobra), ◮ nie ponosimy istotnych strat obliczeniowych, np: • złożoność metody się nie pogorszy, • funkcja nie jest wołana setki/tysiące razy na sekundę. ⋆ Złożoność w rekurencji - zwykle liczba wywołań jest najistotniejsza. ⋆ Złożoność silni: O(n). Przykładowy stos wywołań: 1 Silnia(4) 2 Silnia(3) 3 Silnia(2) 4 Silnia(1) ⋆ Uwaga na lawinowe narastanie wywołań! Rekurencja a ciąg Fibonacciego Przykład absolutnie niewłaściwej implementacji: 1 function FibR(n : integer) : longint; docsity.com 2 begin 3 if n < 3 then 4 FibR := 1 5 else 6 FibR := FibR(n−1) + FibR(n−2) 7 end; Hierarchia wywołań: 1 = 20 FibR(n) 2 = 21 FibR(n-1) FibR(n-2) 4 = 22 FibR(n-2) FibR(n-3) FibR(n-3) FibR(n-4) Można udowodnić, że liczba wywołań > 2n 2 . Koszmarnie dużo! Komputer liczący miliard wywołań na sekundę liczyłby FibR(120) ponad 36 lat. Ciąg Fibonacciego iteracyjnie Uwaga: W kodzie poniżej, array oznacza tzw. tablicę n elementów typu longint tzn. n ponumerowanych wartości tego samego typu. 1 function Fib(n : integer) : longint; 2 var f : array[1..n] of longint; i : integer; { prawie Pascal! } 3 begin 4 f[1] := 1; f[2] := 1 5 for i := 3 to n do 6 f[i] := f[i−1] + f[i−2]; 7 Fib := f[n]; 8 end; Złożoność czasowa O(n), pamięciowa O(n). To już co innego, ale jeszcze ta pamięć! Ciąg Fibonacciego iteracyjnie i oszczędniej z pamięcią 1 function Fib(n : integer) : longint; 2 var pop, ppop, nast : longint; i : integer; 3 begin 4 if n < 3 then 5 Fib := 1 6 else 7 begin 8 pop := 1; ppop := 1; 9 for i := 3 to n do 10 begin 11 nast := pop + ppop; 12 ppop := pop; 13 pop := nast; 14 end; 15 Fib := nast; 16 end 17 end; Złożoność czasowa O(n), pamięciowa O(1). To lubimy! Jak zepsuć potęgowanie? Na przykład tak: 1 function Potega(x : real; n : integer) : real; 2 begin docsity.com 3 if n = 0 then 4 Potega := 1 5 else 6 if n mod 2 = 0 then 7 Potega := Potega(x, n div 2) ∗ Potega(x, n div 2) 8 else 9 Potega := x ∗ Potega(x, n div 2) ∗ Potega(x, n div 2) 10 end; Spartaczone potęgowanie Przykładowa hierarchia wywołań: 1 = 20 Potega(x,17) 2 = 21 Potega(x,8) Potega(x,8) 4 = 22 Potega(x,4) Potega(x,4) Potega(x,4) Potega(x,4) 8 = 23 . . . 8 × Potega(x,2) . . . 16 = 24 . . . 16 × Potega(x,1) . . . 32 = 25 . . . 32 × Potega(x,0) . . . Razem wywołań 1 + 2 + 4 + 8 + 16 + 32 = 2 * 32 - 1 = 63 Złożoność O(2k), gdzie k to głębokość wywołań (rzędu log2 n, gdzie n to wykładnik). Ostatecznie 2log2 n = n, czyli złożoność O(n). Jak na potęgowanie to i tak fatalnie! Potęgowanie poprawnie 1 function Potega(x : real; n : integer) : real; 2 var pom : real; 3 begin 4 if n = 0 then 5 Potega := 1 6 else 7 begin 8 pom := Potega(x, n div 2); 9 if n mod 2 = 0 then 10 Potega := pom ∗ pom 11 else 12 Potega := x ∗ pom ∗ pom 13 end 14 end; Maksymalnie jedno wywołanie wewnątrz, więc lawiny nie będzie! Wywołania dla n = 17 → n = 8 → n = 4 → n = 2 → n = 1 → n = 0. Złożoność O(logn). Indukcja matematyczna Zasada domina: Z faktu, że każda kostka przewrócona przewraca następną oraz że pierwsza została przewrócona wynika gwarancja przewrócenia wszystkich kostek. W matematyce: Aby udowodnić, że prawdziwe jest stwierdzenie Z(n) dla każdej liczby naturalnej n (n = 1,2, . . . ), potrzeba i wystarcza by: 1. prawdziwe było zdanie Z(1), docsity.com