Informatyka od wielomianów - Notatki - Informatyka - Część 1, Notatki'z Informatyka. Opole University
Kowal_86
Kowal_868 March 2013

Informatyka od wielomianów - Notatki - Informatyka - Część 1, Notatki'z Informatyka. Opole University

PDF (845 KB)
10 strona
1000+Liczba odwiedzin
Opis
Notatki dotyczące tematów z dziedziny informatyki: informatyka od wielomianów;
20punkty
Punkty pobierania niezbędne do pobrania
tego dokumentu
Pobierz dokument
Podgląd3 strony / 10
To jest jedynie podgląd.
3 shown on 10 pages
Pobierz dokument
To jest jedynie podgląd.
3 shown on 10 pages
Pobierz dokument
To jest jedynie podgląd.
3 shown on 10 pages
Pobierz dokument
To jest jedynie podgląd.
3 shown on 10 pages
Pobierz dokument

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

⋆ podejścia imperatywne

◮ „liniowe” (Basic – pierwsze wersje)

◮ strukturalne (Pascal, C)

◮ obiektowe (SmallTalk, C++, Object Pascal)

⋆ podejścia deklaratywne

◮ logiczne (Prolog)

◮ funkcyjne (ML, Lisp, Scheme)

Silnia w różnych językach

Schemat blokowy – strona 22

Basic

10 PRINT "Policzymy silni ˛e. Zaczynamy."

20 INPUT "Podaj argument"; arg

30 LET silnia = 1

40 IF arg < 2 THEN GOTO 80

50 LET silnia = silnia ∗ arg 60 LET arg = arg − 1

70 GOTO 40

80 PRINT "Wynik = "; silnia

Silnia w różnych językach

Pascal

1 function Silnia(arg : integer) : longint

2 var s : longint

3 begin

4 s := 1;

5 while arg > 1 do

6 begin

7 s = s ∗ arg; 8 arg := arg − 1

9 end;

10 Silnia := s

11 end;

Scheme

1 (define silnia 2 (lambda (n) 3 (if (< n 2) 1

4 (∗ n (silnia (− n 1))))))

Prolog

1 silnia(0,1) :− !.

2 silnia(N,S) :− N1 is N−1, silnia(N1,S1), S is S1∗N.

docsity.com

Technika dziel i zwyciężaj

⋆ Problemy warto rozkładać na prostsze podproblemy.

⋆ Ang. divide and conquer, pol. dziel i zwyciężaj.

⋆ Ogólny sposób rozwiązywania problemów, doskonale przydający się w programowaniu. Mnóstwo przeróżnych rozwiązań szczegółowych.

⋆ Technika niezależna od języków programowania.

⋆ Przykłady z życia:

◮ wyszukiwanie słowa w słowniku,

◮ budowa domu – podział na mniejsze podzadania, różni wykonawcy specjalizujący się w różnych pracach: murarz, cieśla, stolarz, kowal, . . .

◮ rodzina – podział obowiązków,

◮ budowa komputera – procesory, karty graficzne, monitory, sieci, audio, . . .

⋆ Przykłady z programowania:

◮ mnożenie przez dodawanie,

◮ mnożenie pisemne przez dodawanie i tabliczkę mnożenia do 10,

◮ liczenie potęgi przez redukowanie do mniejszych potęg, ogólniej rekurencja,

◮ metody sortowania (o nich później),

Rekurencja

⋆ Rekurencja (z łac. recurrere, przybiec z powrotem) to odwołanie się definicji do samej siebie.

⋆ Definicje rekurencyjne:

◮ Zbiór liczb naturalnych N: 1. 0 ∈ N, 2. n ∈ N ⇒s(n) ∈ N. W myśl tej definicji 1 = s(0), 2 = s(s(0)) itd. s to operator następnika.

◮ Ciąg Fibonacciego xn =

(

1 o ile n < 3,

xn−1+xn−2 w przeciwnym wypadku.

◮ Silnia n ∈ N: n! =

(

1 o ile n < 2,

n ∗(n−1)! w przeciwnym wypadku.

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

2. z prawdziwości zdania Z(n) wynikała prawdziwość zdania Z(n+1).

Dowód przez indukcję matematyczną

Przykład:

Udowodnić, że dla każdego n = 1,2, . . . liczba 10n−4 jest podzielna przez 6.

Dowód:

Z(n) ≡ „liczba 10n−4 jest podzielna przez 6”

1. Dla n = 1 mamy Z(1) ≡ „101−4 = 6 jest podzielna przez 6”. Prawda.

2. Z(n) ⇒ Z(n+1).

Zakładamy, że „liczba 10n−4 jest podzielna przez 6” i dowodzimy, że „liczba

10n+1−4 jest podzielna przez 6”.

Zauważmy, że

10n+1−4 = 10 ∗10n−10 ∗4+9 ∗4 = 10 ∗(10n−4)+36.

Oba składniki dzielą się przez 6, więc ich suma też. _ [koniec dowodu]

Szukanie w tablicach

Dane: Tablica obiektów.

Cel: Czy tablica zawiera pewien obiekt? Pobranie tego obiektu.

Przykłady:

⋆ Wyszukiwanie słów w słowniku.

⋆ Wyszukiwanie liczb w tablicy liczb.

⋆ Szukanie osoby urodzonej 1.04.2000 w kolekcji danych o osobach.

⋆ Szukanie działki o powierzchni 10 arów w kolekcji działek na sprzedaż. Uwaga: Całkiem inne podejście gdy dane są odpowiednio uporządkowane niż

kiedy porządek jest losowy.

Szukanie liniowe (sekwencyjne)

Gdy porządek jest nieokreślony, trzeba przeglądać całą tablicę element po

elemencie.

1 function SzukajLiniowo(x : array[1..n] of Typ; klucz : TypKlucza) : Typ; 2 var i : integer; 3 begin 4 for i := 1 to n do 5 if KluczObiektu(x) = klucz then 6 begin 7 SzukajLiniowo := x; 8 koniec 9 end; 10 SzukajLiniowo := nie_znaleziono 11 end; Jeśli szukanego elementu nie ma, przejrzymy całą tablicę. Jeśli obiekt w tablicy

istnieje, możemy skończyć wcześniej, ale nie zmienia to średniej złożoności O(n), gdzie n jest liczbą elementów w tablicy.

docsity.com

Szukanie binarne

Jeśli dane są uporządkowane wg klucza wyszukiwania, to można szukać znacznie

krócej niż liniowo.

Dane: tablica x, klucz, zakres szukania [początek,koniec].

Procedura szukania:

⋆ Jeśli klucz < KluczObiektu(x[początek]) lub klucz > KluczObiektu(x[koniec]) to nie znajdziemy.

⋆ środek := (początek + koniec) div 2;

⋆ Jeśli klucz < KluczObiektu(x[środek]) to szukamy w podprzedziale [początek, środek], w przeciwnym przypadku w przedziale [środek, koniec].

Uwaga: Sprawdzanie warunku zawierania się klucza w zakresie, być może warto

wykonać raz przed przystapieniem do szukania, ale nie w każdym (rekurencyjnym)

wywołaniu.

Złożoność O(logn), gdzie n to długość tablicy. Na przykład: szukanie wśród 1000 obiektów wymaga ok. 10 porównań, wśród

miliarda obiektów – ok. 30 porównań.

Szukanie heurystyczne

Metody heurystyczne to takie, które próbują odgadnąć rozwiązanie (nie dają

gwarancji dobrego rozwiązania, ale działają w krótkim czasie).

Jeśli dane są uporządkowane wg klucza wyszukiwania, i znamy mniej-więcej rozkład

wartości klucza to można szukać jeszcze krócej niż binarnie!

Podpowiedź: Szukając w słowniku słowa „binarny” od razu próbujemy szukać w miejscu, gdzie się tego słowa spodziewamy.

Dane: tablica x, klucz, zakres szukania [początek,koniec].

Procedura szukania:

⋆ próg := ZgadnijGdzie(klucz, początek, koniec);

⋆ Jeśli klucz < KluczObiektu(x[próg]) to szukamy w podprzedziale [początek, próg], w przeciwnym przypadku w przedziale [próg, koniec].

Złożoność: nawet O(1), przy odpowiednio dobrej ocenie rozkładu statystycznego kluczy.

Uwaga: Szukanie binarne jest przypadkiem szczególnym szukania heurystycznego

(z dość kiepską heurystyką).

Problem sortowania

⋆ Sortowanie = układanie w odpowiednim porządku.

⋆ Co i jak porządkujemy?

◮ liczby: rosnąco, malejąco, . . .

◮ napisy: alfabetycznie, wg kodów ASCII, wg długości, . . .

◮ dane o osobach: wg daty urodzenia, wg wzrostu, wg nazwiska i imienia, wg wyników w nauce, . . .

◮ . . .

docsity.com

⋆ Przykład: 44 55 12 42 94 18 06 67 06 12 18 42 44 55 67 94

⋆ Można abstrahować od typu obiektów sortowanych oraz relacji porządku.

Metody sortowania

⋆ Prosty wybór

⋆ Bąbelkowe

⋆ Szybkie

⋆ Łączenie

⋆ Zliczanie

⋆ i wiele innych Uwaga na precyzję określeń! element minimalny def = nie większy niż którykolwiek inny element najmniejszy def = mniejszy od każdego innego Algorytmy in situ (łac. „w miejscu”) to takie, które nie wymagają dodatkowej pamięci zależnej od rozmiaru danych wejściowych (złożoność pamięciowa O(1)). Tutaj: trzy pierwsze są in situ, kolejne dwa nie.

Sortowanie przez prosty wybór

Idea: Znajdujemy element minimalny i zamieniamy go z pierwszym, a potem w ten

sam sposób zajmujemy się pozostałymi (pomijając pierwszy).

Przykład: 0 44 55 12 42 94 18 06 67 1 06 55 12 42 94 18 44 67 2 06 12 55 42 94 18 44 67 3 06 12 18 42 94 55 44 67 4 06 12 18 42 94 55 44 67 5 06 12 18 42 44 55 94 67 6 06 12 18 42 44 55 94 67 7 06 12 18 42 44 55 67 94

Liczba porównań: n−1+n−2+. . .+1. Złożoność czasowa O(n2).

Sortowanie bąbelkowe

Idea: Porównujemy i zamieniamy tylko sąsiednie elementy. Po przebiegu przez całą

tablicę, jeden element jest na pewno na swoim miejscu.

docsity.com

komentarze (0)
Brak komentarzy
Bądź autorem pierwszego komentarza!
To jest jedynie podgląd.
3 shown on 10 pages
Pobierz dokument