background image

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 

Projektowanie i analiza algorytmów

Design and analysis of computer algorithms

 

Analiza i projektowanie algorytmów

Analiza algorytmów pozwala odpowiedzieć na pytania:

 Czy dany problem może być rozwiązany na komputerze w dostępnym czasie i 

określonej pamięci ?

 Który algorytm zastosować w danych okolicznościach ?

 Czy istnieje lepszy algorytm (czy jest on optymalny) ?

 Jak uzasadnić, że dany algorytm rozwiązuje postawione zadanie ?

ASD

LJ

S

 

background image

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 

Analiza algorytmów

Aspekty analizy algorytmów:

 Poprawności semantycznej algorytmu.
 Złożoności obliczeniowej: czasowej, pamięciowej.

ASD

LJ

S

Analiza algorytmów uwzględnia: poprawność semantyczną, czas działania, zajętość
pamięci, optymalność, okoliczności użycia algorytmu.

Określanie poprawności algorytmu:

1.

Metoda empiryczna (testowanie programu).

2.

Formalne dowodzenie poprawności algorytmu.

Analiza w aspekcie złożoności obliczeniowej (czasowej i przestrzennej) związana 
jest z tzw. kosztem algorytmu. Projektowanie algorytmu polega na minimalizacji 
tego kosztu.

 

Metody projektowania algorytmów

Metody projektowania algorytmów:



Meoda „dziel i zwyciężaj” (

divide-and-conquer strategy

).



Programowanie dynamiczne (

dynamic programming

).



Rekurencja (

recursive approach

).



Metoda przyrostowa (algorytmy konstrukcyjne) (

constructive method

).



Metoda zachłanna (

greedy approach

).



Metody aproksymacyjne (

aproximation algorithms

).



Metody zrównoleglenia algorytmów (

parallel algorithms

).

ASD

LJ

S

 

background image

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 

Metoda „dziel i zwyciężaj”

Charakterystyka metody:



Podział problemu wyjściowego na mniejsze podproblemy tej samej postaci 
ale mniejszego rozmiaru,



Rozwiązanie podproblemów, na podstawie których wyznaczane jest  

rozwiązania końcowe,



Stosowana w połączeniu z rekurencją, 



Przykład podejścia zstępującego w projektowaniu (top down), 



Rozwiązywane przykładowe problemy: sortowanie „quicksort”, sortowanie 

„przez scalanie”, silnia,  przeszukiwanie ciągu itd.

ASD

LJ

S

 

Metoda programowania dynamicznego

Charakterystyka metody:



Rozszerzenie i optymalizacja strategii „dziel i zwyciężaj”,



Podział problemu na mniejsze podproblemy (w tym kontekście metoda jest 

podobna do metody „dziel i zwyciężaj”), które są najpierw rozwiązywane a 

wyniki przechowywane (np. w tablicy),



Wykorzystanie przechowywanych rozwiązań podproblemów do 

konstruowania rozwiązania końcowego,



Przykład podejścia wstępującego w projektowaniu (

bottom-up

),



Rozwiązywane problemy: ciąg fibonacciego, dwumian Newtona, zagadnienia 

najkrótszej drogi w gafie, itd.

ASD

LJ

S

 

background image

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 

Złożoność obliczeniowa algorytmów

Computational Complexity

Hartmanis J., Stearns R. „On the Computational
Complexity of Algorithms”, 1965)

 

Złożoność obliczeniowa

ASD

LJ

S

Zakładamy, że rozpatrywane algorytmy realizowane są na maszynie  RAM (

Random

Access Machine

)  - koncepcja maszyny Neumanna (

Stored program concept

).

Cechy maszyny RAM:

1.

Rozkazy wykonywane są sekwencyjnie (

pobierz-dekoduj-wykonaj rozkaz

).

2.

Zbiór rozkazów zawiera rozkazy przesłań, arytmetyczne, logiczne, 
porównania.

Cele analizy czasowej algorytmu:

1.

Porównanie różnych algorytmów rozwiązujących te same problemy.

2.

Przewidywanie wydajności algorytmów w nowym środowisku obliczeniowym.

3.

Określenie czasowych wartości parametrów algorytmów.

Miara porównania algorytmów powinna być niezależna od: komputera, języka 
programowania, systemu operacyjnego, umiejętności programisty, szczegółów 
implementacji.

 

background image

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 

Złożoność obliczeniowa

Podstawowe rodzaje złożoności.



Złożoność czasowa (

time complexity, running time

):

-

czasu wykonania wyrażony w standardowych jednostkach czasu lub 
liczbie cykli procesora (niemożliwe na etapie algorytmu i pseudokodu),

-

czasu wykonania wyrażany w ilościach tzw. operacji dominujących
(upraszcza analizę).



Złożoność pamięciową (

space complexity

):

-

zapotrzebowanie na pamięć mierzone w: B, kB, MB, GB, TB,

-

ilość użytych zmiennych typów prostych np. integer lub real.

ASD

LJ

S

Czasowa złożoność obliczeniowa - funkcja określająca czas potrzebny do 
wykonania algorytmu dla konkretnych danych.

Złożoność pamięciowa - funkcja określająca liczbę komórek pamięci potrzebnych 
do wykonania algorytmu dla konkretnych danych.

 

Operacje podstawowe

Typowe operacje elementarne (podstawowe, 

basic operations

):



Operacje arytmetyczne, logiczne, relacyjne,



Podstawienie,



Indeksowanie, odwołanie do pola struktury,



Inicjalizacja wywołania funkcji,



Przekazywanie wartości do funkcji,



Operacje we/wy,



„Wizyta” w węźle, przejście po krawędzi (algorytmy grafowe).

Przykłady operacji, które nie są elementarnymi to instrukcje: WHILE, REPEAT, FOR.

ASD

LJ

S

 

background image

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 

Rozmiar danych wejściowych

Instancja problemu (

problem instant

) - zestaw danych wejściowych.

Instancje problemu rozróżnia się ze względu na: rozmiar egzemplarza danych 
(najczęściej liczbę danych określonych typów) oraz inne właściwości (np. 
początkowe uporządkowanie elementów).

Określając bardziej formalnie, rozmiar danych wejściowych wyrażanych liczbą n jest 
to liczba bitów potrzebnych do jej reprezentowania w kodzie NBC (

Natural Binary

Code

) naturalnym kodzie binarnym.

ASD

LJ

S

Rozmiar danych wejściowych (

input size, size of the input

) - liczba pojedynczych danych 

wchodzących w skład struktury danych. Liczbę tą najczęściej oznaczmy przez n (w 
niektórych przypadkach wymaga doprecyzowania).

Dla wartości n, liczba litów wynosi 

lgn+1, n=100, 1100100, lg100+1 → 7 bitów. 

x „podłogą” liczby rzeczywistej x∈R nazywamy największą liczbę całkowitą nie 
większą niż x.

 

Rozmiar danych wejściowych

Rozmiar danych wejściowych (przykłady).

ASD

LJ

S

1.

W problemie sortowania ciągu skończonego a

1

a

2

, ... , a

n

rozmiarem danych 

jest liczba n.

2.

W przypadku przetwarzania n-wierszowej i m-kolumnowej tablicy rozmiarem 

danych jest liczba n* m.

3.

Dla algorytmów grafowych do okreslenia rozmiaru danych wejściowych 

można użyć liczby wierzcholków i liczby łuków, występujacych w tym grafie.

4.

W algorytmie wyznaczania n-tego wyrazu ciągu Fibonacciego n będzie 

rozmiarem danych i jednocześnie daną wejściową.

 

background image

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 

Złożoność obliczeniowa

Wyznaczanie czasowej złożoności obliczeniowej algorytmu.

Zakładamy, że czas działania  algorytmu jest proporcjonalny do liczby wykonań
poszczególnych instrukcji zawartych wewnątrz kolejnych pętli.

ASD

LJ

S

Przykład. Wyznaczanie sumy trzecich potęg n najmniejszych liczb całkowitych.

Sum poteg(n)

liczba wykonań

{

1.

s=0; 

1

2.

x=1;

1

3.

WHILE(x≤n){

(n+1)

4.

y=x*x*x;

n

5.

s=s+y;

n

6.

x=x+1;

n

}

7.

return(s);

1

}

Funkcja czasowej złożoności algorytmu T(n) (liczba wykonań poszczególnych 
instrukcji): T(n) = 4n  + 4

 

Złożoność obliczeniowa

Przykład. Dany jest ciąg n liczb całkowitych. Należy wyznaczyć początek i koniec 
fragmentu podciągu, dla którego suma elementów jest największa.

ASD

LJ

S

Max pciag V1(A,n,p,k) 
//A-tablica indeksowana od 1 do n

liczba wykonań

{

maxsum=MinInt;

1

p=1;

1

k=1;

1

FOR(i=1,2,…,n)

n

FOR(j=i,i+1,…,n){

(n-i+1)

asum=0;

J(n)

FOR (k=i,i+1,…,j)

(j-i+1)

asum=asum+A[k];

K(n)

IF (asum>maxsum){

J(n)

maxsum=asum;

J(n)

p=i;

J(n)

k=j;

J(n)

}

}

return(maxsum,p,k);

1

}

 

background image

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 

Złożoność obliczeniowa

Liczba operacji elementarnych w algorytmie Max pciag V1 zależy od: 

ASD

LJ

S



Rozmiaru danych wejściowych  n (liczba iteracji poszczególnych pętli).



Wartości danych (spełnienia warunku: asum > maxsum).

Liczba wykonań instrukcji w pętli po k:

n

n

n

i

n

i

n

i

j

n

K

n

i

n

i

j

n

i

j

i

k

n

i

j

n

i

3

1

2

1

6

1

2

)

2

)(

1

(

)

1

(

1

)

(

2

3

1

1

1

+

+

=

+

+

=

+

=

=

=

=

=

=

=

=

Liczba wykonań instrukcji w pętli po j:

n

n

n

n

i

n

n

J

n

i

n

i

j

n

i

2

1

2

1

2

)

1

(

)

1

(

1

)

(

2

1

1

+

=

+

=

+

=

=

=

=

=

Złożoność pesymistyczna:

4

6

17

3

6

1

1

)

(

)

(

5

3

)

(

2

3

+

+

+

=

+

+

+

=

n

n

n

n

K

n

J

n

T

 

Złożoność obliczeniowa

ASD

LJ

S

Max pciag V2(A,n,p,k)

//A-tablica indeksowana od 1 do n

liczba wykonań

{

maxsum=MinInt;

1

p=1;

1

k=1;

1

FOR(i=1,2,…,n){

n

asum=0;

I(n)

FOR (k=i,i+1,…,n) {

(n-i+1)

asum=asum+A[j];

J(n)

IF (asum>maxsum){

J(n)

maxsum=asum;

J(n)

p=i;

J(n)

k=j;

J(n)

}

}

}
return(maxsum,p,k;

1

}

 

background image

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 

Złożoność obliczeniowa

ASD

LJ

S

Liczba wykonań instrukcji w pętli wewnętrznej:

J(n) – liczba obrotów pętli po j.

I(n) – liczba obrotów pętli po i.

Złożoność pesymistyczna:

n

n

n

n

i

n

J

n

i

n

i

j

n

i

2

1

2

1

2

)

1

(

1

)

(

2

1

1

+

=

+

=

=

=

=

=

=

n

n

I

=

)

(

4

2

7

2

5

1

)

(

5

)

(

3

)

(

2

+

+

=

+

+

+

=

n

n

n

J

n

I

n

T

 

Złożoność obliczeniowa

ASD

LJ

S

Max pciag V3(A,n,p,k)

//A-tablica indeksowana od 1 do n

liczba wykonań

{

maxsum=MinInt;

1

p=1;

1

k=1;

1   

i=1;

1

asum=0;

1

FOR(j=1,2,…,n){

n

asum=asum+A[j];

J(n)

IF (asum>maxsum){

J(n)

maxsum=asum;

J(n)

p=i;

J(n)

k=j;

J(n)

}

IF (asum < 0){

J(n)

i=j+1;

J(n)

asum=0;

J(n)

}

}
return(maxsum,p,k;

1

}

J(n) – liczba obrotów 

pętli po j.

J(n) = n

6

8

)

(

+

= n

n

T

 

background image

 

10 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 

Złożoność obliczeniowa

ASD

LJ

S

Rozmiar 
problemu  n

Algorytm
Max pciag V1

Złożoność czasowa (liczba elementarnych operacji)

Algorytm
Max pciag V2

Algorytm
Max pciag V3

10

500

300

100

10

2

200 10

3

25 10

3

10

3

10

3

2 10

8

2.5 10

6

8 10

3

10

4

1.5 10

11

2.5 10

8

8 10

4

10

5

1.5 10

14

2.5 10

9

8 10

5

Porownanie czasów  wykonania algorytmów 

 

Złożoność obliczeniowa

ASD

LJ

S

Rozmiar problemu  
n

Algorytm
Max pciag V1

Złożoność czasowa (w jednostkach czasowych)

Algorytm
Max pciag V2

Algorytm
Max pciag V3

10

0.5 ms

0.3 ms

0.1 ms

10

2

0.2 s

25 ms

1 ms

10

3

200 s

2.5 s

8 ms

10

4

45 godz.

5 min

0.8 ms

10

5

4.5 lat

50 min

0.8 s 

Założony czas wykonywania elementarnej operacji wynosi 10

-6

s.

Porownanie czasów  wykonania algorytmów 

Konwersja sekund

10

2

→ 2 min

10

6

→ 1,5 tyg. 

10

9

→ 30 lat

10

4

→ 3 godz.

10

8

→ 3 lata 

10

10

→ 300 lat

 

background image

 

11 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 

Złożoność obliczeniowa

ASD

LJ

S

Rozmiar problemu  
n

Algorytm
Max pciag V1

Złożoność czasowa (liczba elementarnych operacji)

Algorytm
Max pciag V2

Algorytm
Max pciag V3

10

0.5 

µs 

0.3 

µs

0.1 

µs 

10

2

0.2 ms

0.025 ms

0.001 ms

10

3

0.2 s

2.5 ms

0.008 ms

10

4

3 min

0.25 s

0.08 ms

10

5

45 godz

2.5 s

0.8 ms

Porownanie czasów  wykonania algorytmów 

Założony czas wykonywania elementarnej operacji wynosi 10

-9

s.

 

Złożoność obliczeniowa

ASD

LJ

S

Rozmiar 
problemu  n

Algorytm
Max pciag V1

Złożoność czasowa (liczba elementarnych operacji)

Algorytm
Max pciag V2

Algorytm
Max pciag V3

10

0.5 ns

0.3 ns

0.1 ns

10

2

0.2 µs

25 ns

1 ns

10

3

0.2 m s

2.5 µs

8 ns

10

4

0.15 s

0.25 ms

80 ns

10

5

3 min

2.5 ms

0.8 µs

Porownanie czasów  wykonania algorytmów 

Założony czas wykonywania elementarnej operacji wynosi 10

-12

s.

 

background image

 

12 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Operacje dominujące

O złożoności czasowej algorytmu decydują operacje, które zwykle umieszczone są
w najbardziej wewnętrznej pętli. 
Operacje takie nazywamy dominującymi (

dominant operations

).

ASD

LJ

S

Liczba operacji dominujących jest: 

1.

Proporcjonalna do liczby wszystkich operacji algorytmu.

2.

Rzędu liczby wszystkich operacji.

3.

Proporcjonalna do czasu działania programu implementującego algorytm.

Problem

Operacja

Wyszukiwanie elementu x na liście

Porównywanie x z pozycją na liście

Mnożenie dwóch macierzy 

Mnożenie dwóch liczb typu real

Sortowanie liczb

Porównywanie dwóch liczb, zamiana liczb

Trawersowanie grafu

Operacja na węźle, krawędzi

 

background image

 

13 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 

Asymptotyczna  złożoność obliczeniowa

Notacje  asymtotyczne

(Asymptotic notation, Order notation)

ASD

LJ

S

 

Notacje  asymtotyczne

Asymptotyczne ograniczenie górne (

asymptotic upper bound

).

O-notacja.

Funkcja f(n) jest co najwyżej rzędu g(n) ( f(n)=O(g(n)) ) jeżeli:

(

∃ c>0 ) (∃ n

0

≥ 0 ) ∀ n ≥ n

0

zachodzi  f(n)

≤ c g(n).

f(n) =O(g(n))  gdy lim

n

→∞

f(n)/g(n) = 0.

Inna definicja O-notacji:

f(n) =O(g(n))

≡ lim 

n

→∞

sup

f(n)/g(n) < ∞

Paul  Bachman (1892)

g(n) 

≠ O(f(n)).

ASD

LJ

S

 

background image

 

14 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 

Notacje  asymtotyczne

Symbol O(g(n)) oznacza zbiór funkcji f: N

→R

+

zdefiniowany następująco:

O( g(n) ) = {f

∈ R

+

: istnieje taka stała c>0 i n

0

∈N, że f(n)≤c g(n)  dla 

każdego n > n

0

}

Równoważne zapisy: f(n)=O(g(n)), f

∈O(g(n)).

Sens notacji O polega na istnieniu „asymptotycznego ograniczenia górnego”, 

pozwalającego oszacować od góry wartości funkcji f przez wartości funkcji g.

ASD

LJ

S

 

Notacje  asymtotyczne

1.   f(n) = n

2

/2 = O(n

3

)

ASD

LJ

S

0

2

1

lim

2

/

lim

3

2

=

=

n

n

n

n

n

2.

f(n) = nlogn = O(n

2

)

log

b

a = log

c

a / log

c

b

0

2

ln

/

1

lim

2

ln

ln

lim

log

lim

2

=

=

=

n

n

n

n

n

n

n

n

n

Wniosek:

nlogn = O(n

2

)  ale  n

2

≠ O(nlogn)

 

background image

 

15 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 

O – notacja

3.  f(n) = n

n ≤ 1 n

2

dla

n ≥ 1

f(n) = O(n

2

)

4.

f(n) = n

2

+5n 

n

2

+5n ≤ 2n

2

dla 

n ≥ n

0

= 5,  stąd  c=2  oraz  n

0

= 5 

n

2

+5n = O(n

2

dla c=6  oraz  n

0

= 1 zachodzi:  n

2

+5n ≤ n

2

+5n

= 6 n

2

5.

f(n) = n

n

2

= O(n

2

+ 5n)

n

2

≤ 1 (n

2

+5n) dla 

c=1 oraz  n

0

=0

ASD

LJ

S

 

O – notacja

7.    f(n) = 2n

2

+ 3n + 1 = O(n

2

)

≥ 6  

≥ 3,8    ≥ 3,2  ≥ 2,9  ≥ 2,7   

→ 2

n

0

2   

3  

4     

5      

→ ∞

Wartości c, n

0

otrzymujemy, rozwiązując nierówność:

2n

2

+ 3n + 1 

≤ cn

2

6.

f(n) = 2n

2

+ 15n + 5lg n + 50

f(n) = 2n

+ 15n + O(lg n)

f(n) = 2n

2

+ O(n) 

f(n) = O(n

2

)

ASD

LJ

S

 

background image

 

16 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 

O – notacja

Funkcje T(n) czasowej złożoności określonego algorytmu.

4

2

7

2

11

2

1

)

(

2

3

+

+

+

=

n

n

T

n

n

Dla n > 12 zachodzi:

n

n

n

T

3

3

)

(

2

1

<

<

2

)

1

(

)

(

=

n

n

n

T

1.

2

2

)

(

2

)

1

(

2

n

n

n

n

n

=

2.

Dla n>0 zachodzi:

T(n)=O(n

2

)

ASD

LJ

S

T(n)=O(n

3

)

 

O – notacja

n

n

T

n

10

)

(

2

+

=

Dla n 

≥ 10 zachodzi:

1.

ASD

LJ

S

n

n

n

n

T

2

2

2

10

)

(

+

=

Możemy przyjąć c=2 oraz n

0

=10, w celu stwierdzenia, że T(n)=O(n

2

).

 

background image

 

17 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 

Kategorie złożoności 

ASD

LJ

S

Określenie werbalne

Określenie formalne

stała

O(1)

liniowa

O(n)

subliniowa

O(n

r

) 0<r<1

logarytmiczna

O(lg n)

liniowo - logarytmiczna

O(n lg n)

kwadratowa

O(n

2

)

subkwadratowa

O(n

r

) 1<r<2

wielomianowa

O(n

k

) k

≥1

wykładnicza

O(r

n

)  r>1

Kategorie złożoności (

complexity categories

) są to zbiory funkcji, które mają takie 

samo asymptotyczne ograniczenie.

 

O – notacja

ASD

LJ

S

Dla małych n algorytm2 o większej asymptotycznej złożoności obliczeniowej może 
okazać się lepszy. Algorytm lepszy asymptotycznie nie zawsze jest lepszy dla 
małych n.

Algorytm1

Algorytm2

 

background image

 

18 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 

Typowe funkcje złożoności



T(n) = O(1):  czas realizacji algorytmu jest stały, Większość instrukcji wykonuje 

się raz lub kilka razy.



T(n) = O(n): algorytm działa w czasie liniowym (

linear time

), na każdy z n 

elementów wejściowych potrzebna jest niewielka ilość czasu przetwarzania. 



T(n) = O(lgn): algorytm nieznacznie spowalnia ze wzrostem n. Taka zależność

występuje w przypadkach, kiedy rozwiązywanie polega na transformacji  

wyjściowego zadania na szereg cząstkowych zadań, transformacji  redukującej 

rozmiar zadania wyjściowego (np. przeszukiwanie binarne). 

ASD

LJ

S

 

Typowe funkcje złożoności



T(n) = O(nlgn): Przypadek w którym problem jest rozwiązywany poprzez 
rozbicie go na niezależne podproblemy o mniejszym rozmiarze, a następnie 
połączenie otrzymanych rozwiązań (np. sortowanie przez scalanie).



T(n) = O(n

k

): Algorytm nadaje się do rozwiązywania relatywnie niedużych 

zadań. Przypadek dotyczy z reguły przetwarzania wszystkich par n elementów 
wejściowych (np. przetwarzanie dwuwymiarowych tablic).



T(n) = O(2

n

): Algorytmy w niektórych przypadkach są akceptowane w 

rozwiązaniach praktycznych. Kiedy n podwaja się czas rośnie do kwadratu (np. 
wyznaczanie wszystkich podzbiorów zbioru).

ASD

LJ

S

 

background image

 

19 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 

Typowe funkcje złożoności

Wartości najczęściej spotykanych funkcji złożoności.

ASD

LJ

S

n

lg

nlgn

n

2

10

3

33

100

100

7

664

10000

1000

10

9966

1000000

10000

13

132877

100000000

 

Typowe funkcje złożoności

ASD

LJ

S

Kategorie złożoności (

complexity categories

).

 

background image

 

20 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 

Złożoność asymtotyczna

A1 //Ciąg instrukcji
{
s1; s2; ...; sn;
}

O(1)

A2 //Pojedyncza pętla
{

For i=1,2,..., n 

s;

}

nO(1) = O(n).

A3 //Podwójna pętla
{
For i:=1,2,...,n 

For j:=1,2,...,n 

s;

}

O(n

2

)

A4 //Podwójna pętla,zaleŜność indeksów
{

For i:=1,2,..., n 
For j:=1,2,..., i 

s;

}

)

(

)

2

)

1

(

(

)

(

2

1

n

O

n

n

O

i

O

n

=

+

=

ASD

LJ

S

 

Własności notacji

Własności „O notacji:



Mnożenie przez stałą:

k f(n) = O(f(n))

k O(f(n)) = O(f(n))

O(k f(n)) = O(f(n))



Suma:

O(f

1

(n))+ ...+ O(f

k

(n)) = O(f

1

(n) + ...+ f

k

(n)) 



Iloczyn:

O(f(n)) O(g(n)) =  O(f(n) g(n))



Przechodniość:

f(n) = O(g(n)) i  g(n) = O(h(n)) 

⇒ f(n) = O((h(n))

ASD

LJ

S

 

background image

 

21 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 

Własności notacji



Wielomian wyższego stopnia rośnie szybciej niż wielomian stopnia niższego:

n

=O(n

s

jeżeli

≤ r ≤ s



Funkcja wykładnicza rośnie szybciej niż funkcja wielomianowa:

n

k

=O(b

n

dla

b > 1, k 

≥ 0



Funkcja logarytmiczna rośnie wolniej niż wielomianowa:

log

b

n =O(n

k

dla

b > 1, k > 0



Wszystkie logarytmy rosną w tym samym stopniu:

log

b

n =O(log

d

n)  dla

b, d > 1

ASD

LJ

S

 

Notacje  asymtotyczne

Ω - notacja.

Asymptotyczne ograniczenie dolne (

asymptotic lower bound

).

Funkcja f(n) jest co najmniej rzędu g(n) ( f(n)=Ω(g(n)) ) jeżeli:

(

∃ c>0 ) (∃ n

0

≥0 ) ∀ n > n

0

zachodzi:  f(n) ≥ c g(n)

f(n) = Ω (g(n)),  gdy lim

n

→∞

f(n)/g(n) = +

Inna definicja Ω-notacji:

f(n) = Ω(g(n)) ≡ lim 

n

→∞

inf

f(n)/g(n)> 0

g(n) = O(f(n)).

ASD

LJ

S

Notacja Ω wymaga istnienia „asymptotycznego ograniczenia dolnego”, 

pozwalającego oszacować „od dołu” funkcję f przez funkcję g.

 

background image

 

22 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 

Ω - notacja

1. f(n) = 5n

2

5n

2

≥ 1

⋅ n

2

dla c = 1,  n

0

= 0,  n ≥ n

0

f(n) = Ω(n

2

2

)

1

(

)

(

=

n

n

n

f

Dla n 

?

2 zachodzi (n-1) 

?

n/2

4

2

2

2

)

1

(

)

(

2

n

n

n

n

n

n

f

=

=

c = 1/4,  n

= 2 

f(n) = Ω(n

2

).

2.

2

2

)

(

2

)

1

(

)

(

2

n

n

n

n

n

n

f

=

=

c = 1/2,  n

0

= 0

f(n) = O(n

2

).

ASD

LJ

S

 

Θ

Θ

Θ

Θ - notacja

Θ

- notacja.

Funkcja f(n) jest rzędu Θ(g(n)) ( f(n)=Θ(g(n) ) ) jeżeli:

(

∃ c

1

, c

2

>0 ) (

∃ n

0

≥0 ) ∀ n ≥ n

0

zachodzi: c

1

g(n)

≤f(n)≤c

2

g(n)

f(n) = Θ(g(n)),  gdy lim

n

→∞

f(n)/g(n) = const

Θ(g(n)) = O(g(n)) 

∩ Ω(g(n))

Ω( )

O( )

Θ( )

ASD

LJ

S

Sens notacji Θ polega na istnieniu „asymptotycznego ograniczenia dolnego i górnego”, 
pozwalającego oszacować „od dołu” i „od góry” funkcję f przez funkcję g.

 

background image

 

23 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 

Θ

Θ

Θ

Θ - notacja

4

2

7

2

11

2

1

)

(

2

3

+

+

+

=

n

n

n

n

T

3

3

)

(

2

1

n

n

T

n

<

<

Dla c

1

= 1/2, c

= 1 oraz n

= 12

T(n)= O(n

3

∩ Ω(n

3

)= Θ(n

3

)

Dla c

1

= 1/4, c

= 1/2 oraz n

= 2

2

)

1

(

)

(

=

n

n

n

T

2

2

2

1

)

(

4

1

n

n

T

n

<

<

T(n)= O(n

2

∩ Ω(n

2

)= Θ(n

2

)

O

2n

2

3n

2

+6

5n

2

+2n

5n+7
2nlgn

2n

2

3n

2

+6

5n

2

+2n

2

n

+4n

4n

3

+3n

2

O(n

2

)

(n

2

)

O( )

5n+7
2nlgn

Ω( )

Θ

( )

2n

2

3n

2

+6

5n

2

+2n

2

n

+4n

4n

3

+3n

2

Θ

(n

2

)= O(n

2

)∩

(n

2

)

ASD

LJ

S

 

Złożoność obliczeniowa

Nierealizowalność algorytmu jest wewnętrzną cechą algorytmów o złożoności

wykładniczej.

ASD

LJ

S

Rozmiar danych n

30

50

60

Liczba operacji 2

n

0.1 10

10

10

15

10

18

Czas działania
(10

-10  

s/op.)

0.1 s

10

5  

s

(28h)

10

8  

s

(3 lata)

Czas działania

(10

-13  

s/op.)

0.1 10

-3  

s

10

2  

s

10

5  

s

(28h)

Charakteryzowanie w sposób asymptotyczny efektywności algorytmu jest abstrakcją, 
w której pomija się szczegóły. Posługiwanie się tą miarą wymaga uświadomienia 
sobie szczegółów, które taka abstrakcja ukrywa.

 

background image

 

24 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 

Rodzaje złożoności obliczeniowej

 Złożoność pesymistyczna (

worst-case complexity

),

 Złożoność oczekiwana (

average-case complexity

),

 Złożoność optymistyczna (

best-case complexity

).

ASD

LJ

S

 

Rodzaje złożoności obliczeniowej

Oznaczenia.

D

n

- zbiór możliwych zestawów danych (instancji) o rozmiarze n

I  - zestaw danych, element zbioru D

n

(I 

∈ D

n

)

t(I) - liczba operacji dominujących dla zestawu danych wejściowych I

∈D

n

X

n

- zmienna losowa, której wartością jest t(I) dla I

∈D

n

p

n,k

– prawdopodobieństwo tego, że dla zestawu danych I wykonano k 

operacji dominujących, p

n,k

=P

n

(X

n

=k)

P

n

- rozkład prawdopodobieństwa ( z reguły równomierny) zmiennej losowej  X

n

.

ASD

LJ

S

 

background image

 

25 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 

Rodzaje złożoności obliczeniowej

 Złożoność pesymistyczna

(worst case running time)

T

worst

(n) = sup { t(I): I

∈D

n

}

 Złożoność oczekiwana

(average case running time) (wartość oczekiwana 

zmiennej losowej X

n

)

 Złożoność optymistyczna

(worst case running time)

T

best

(n) = inf { t(I): I

∈D

n

}

T

ave

(n) = E(X

n

) =

Σ

k

≥0

k p

n,k

ASD

LJ

S

 

Wrażliwość obliczeniowa algorytmu

 Wrażliwość pesymistyczna

(worst- case sensitivity):

wcs

(n) = T

worst

(n) – T

best

(n) = sup { t(I

1

) - t(I

2

): I

1

, I

2

∈D

n

}

 Wrażliwość oczekiwana

(average- case sensitivity):

δ

acs

(n) = dev(Xn) =  

√ Var(Xn) 

gdzie:  dev(X

n

) – standardowe odchylenie zmiennej losowej X

n

,

var(X

n

) – wariancja zmiennej losowej X

n

,

p

k

k

n,

2

k≥0

n

)

(

X

n

)

(

(

)

X

var(

=

E

ASD

LJ

S

 

background image

 

26 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 

Złożoność obliczeniowa

Search (A,n,x) 
//A-tablica indeksowana od 1 do n+1
{

A[n+1]=x;

1.

ind=1;

2.

WHILE (ind≤n and A[ind]≠x){

3.

ind=ind+1;

}

4.

IF (ind>n) {

5.

ind=0;

}

6.

return(ind)

}

Przykład.

Przeszukiwanie liniowe (n+1)-elementowej tablicy A ze względu na pierwsze
wystąpienie elementu o wartości x. Poszukiwane elementy znajdują się na miejscach 
A[1], A[2], …, A[n].

Operacja dominująca: porównywanie elementów tablicy z wartością x.

ASD

LJ

S

 

Złożoność obliczeniowa

 Analiza najgorszego przypadku:

- x zajmuje ostatnią pozycję T

worst

(n) = n,

- x nie występuje w tablicy

T

worst

(n) = n+1.

 Analiza średniego przypadku:

Założenia:
-

wszystkie elementy tablicy są różne,

-

x należy do tablicy A,

-

x może być na każdej pozycji z jednakowym prawdopodobieństwem.

T

ave

(n)

p

n,i

t (I

i

) = 

Σ

i=1 

i = 

i = 

2

n(n+1) = 

2

(n+1) 

Σ

i=1 

Σ

i=1 

ASD

LJ

S

p

n,i

dla i = 1,2,..,n

 

background image

 

27 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 

Złożoność obliczeniowa

Przypadek kiedy x może nie znajdować się w tablicy:

I

– zestaw danych dla przypadku, gdy x jest na i-tej pozycji,

I

n+1

– zestaw danych, gdy przypadku, gdy x nie ma  w tablicy,

q - oznacza prawdopodobieństwo tego, że x jest w tablicy, 

Dla 1

≤ i ≤ n:  p

n,i

=q/n, 

t(I

i

)=i

p

n+1,n

=1-q,

t(I

n+1

)=n+1

T

ave

(n)

p

n,i

t (I

i

) = 

Σ

i=1 

n+1

q

i +(1 –q) (n+1)= q

2n

n(n+1) 

Σ

i=1 

+ (1- q)(n+1)

Dla q=1:

T

ave

(n) = (n+1)/2,

Dla q=1/2: 

T

ave

(n) = (n+1)/4 +(n+1)/2 

ASD

LJ

S

 

Wrażliwość algorytmu

Przeszukiwanie liniowe tablicy.

1.

Wrażliwość pesymistyczna:

wcs

(n) = T

worst

(n) – T

best

(n) = O(n)-O(1)= O(n)

2.

Wrażliwość oczekiwana:

n

n

n

n

n

n

n

n

n

n

n

n

n

n

n

n

n

n

i

n

n

n

I

t

X

Var

n

i

n

i

i

n

2

2

2

2

2

2

1

12

1

12

1

)

3

3

2

4

(

12

1

4

)

1

(

6

)

1

2

)(

1

(

)

4

)

1

(

4

)

1

(

)

1

(

2

6

)

1

2

)(

1

(

(

1

2

1

1

1

2

1

)

(

)

(

)

(

)

(

=

+

+

=

=

+

+

+

=

+

+

+

+

+

+

=

=

+

=

+

=

=

δ(n) ≈ √(n

2

/12)  

≈ 0.29 n

ASD

LJ

S

 

background image

 

28 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 

Złożoność obliczeniowa

Złożoność obliczeniowa w każdym przypadku (

every-case time complexity

).

SORT(n) 
// n–rozmiar danych we.
}

For i=1,2,...,n-1 {

For j=i+1, ...,n {

Operacja podstawowa

}

}

}

T

ave

(n) = T

best

(n) = (n-1) + (n-2) + ...+1 

= ½ (n (n-1)) = ½ (n

2

– n)

T

ec

(n) = (n-1)n/2  

→ selection_sort.

ASD

LJ

S

MULT(n) 

//n–rozmiar danych we.

{

FOR i=1,2,...,n         

FOR j=1,2,...,n 

FOR k:=1,2,...,n{

Operacja dominująca

}

}

T

ave

(n) = T

best

(n) = n

3

T

ec

(n) =  n

3

→ mnożenie tablic

dwuwymiarowych,

 

Złożoność obliczeniowa

Wyszukiwanie binarne (iteracyjne).

Sformułowanie zadania: Czy x znajduje się w uporządkowanej n-elementowej

tablicy A?.

Dane wejściowe:

-

Tablica uporządkowana A liczb, (A[1] 

≤ A[2] ≤ ... ≤ A[n]).

-

Liczba  o wartości x.

Dane wyjściowe:

Liczba całkowita ind, taka że albo 1

≤ ind ≤ n, wtedy A[ind]=x, albo ind=0  wówczas

elementu równego x nie ma w tablicy (

∀ j takiego że p ≤ j ≤ k, A[j]≠x oznacza  brak 

elementu x w tablicy).

ASD

LJ

S

 

background image

 

29 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 

Wyszukiwanie binarne

Search binary (A,p,k,x)
{

lewy=p; 
prawy=k; 
ind=0;
WHILE (lewy≤prawy and ind=0){

q=(prawy+lewy)/2;
IF (x=A[q]) ind=q;
IF (x<A[q]) prawy=q-1 

ELSE (x>A[q])lewy=q+1;

}

}

Załóżmy n = 2

5

A[16]A[24]A[28]A[30]A[31]A[32] A[32]

1

2

3

4

5

6

A[16]     

A[24]

A[28]     A[30]  A[31 ] A[32]

1

2

3

4

5

6

Wywołanie procedury: 

Binary_search (A,1,n,x)

Liczba obrotów iteracji: 

lgn+1=lg32+1=6

ASD

LJ

S

 

Wyszukiwanie binarne

Załóżmy n = 2

6

A[16]A[24]A[28]A[30]A[31]A[32] A[32]

1

2

3

4

5

6

A[1]     

A[32] 

A[64]

1

A[16]A[24]A[28]A[30]A[31]A[32] A[32]

1

2

3

4

5

6

A[16]     

A[24]

A[28]     A[30]  A[31 ] A[32]

1

2

3

4

5

6

Liczba obrotów iteracji: 

lg n+1=lg64 +1=7

ASD

LJ

S

 

background image

 

30 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 

Wyszukiwanie binarne

n=2

k

T(1) = 1
T(2) = 2
T(4) = 3

...............

T(32) = 6

T(n) = log n+1

1.

T(1)= 1

2.

Założenie:

T(n) = logn + 1

Teza:

T(2n) = log(2n) + 1

Dw.

T(2n) = T(n) + 1 = (log n + 1) + 1 = (log n + lg 2) + 1 = log 2n + 1;

⇐ T(2n) = log 2n + 1 = (log n + 1) + 1 = T(n) + 1;

T(n) = O(log n)

Dla 2

k

< n < 2

k+1

zachodzi T(2

k

) < T(n) < T(2

k+1

)

ASD

LJ

S

 

Wyszukiwanie liniowe

Search lin (A,n,x) 
{

A[n+1]=x

ind=1;

WHILE(ind≤n ∧ A[ind]≠x){

ind=ind+1;

}
IF (ind>n) 

ind=0;

return(ind);

}

Złożonośc czasowa algorytmu : Search lin:  T(n) = T(n)=n O(1)= O(n) O(1)=O(n). 
 

Rozm. tab.       Wyszuk. liniowe          Wyszuk. binar. 
 

    128                    128                            8 
     1024                    1024                           11 
     1048576              1048576                     21 

4 294 967 296      4 294 967 296              31 

 

ASD

LJ

S

 

background image

 

31 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 
 

Złożoność pamięciowa

Space complexity

 

Złożoność pamięciowa

Rodzaje złożoności  pamięciowej:



Złożoność pamięciowa oczekiwana (expected space complexity),



Złożoność pamięciowa najgorszego przypadku (worst-case space complexity).

Złożoność pamięciowa – wielkość obszaru pamięci (liczba komórek pamięci)
używanych przez program implementujący algorytm. Jednostki: B, kB, MB, GB, TB.

Dane istotne (

essential data

) – dane, które nie mogą być pominięte w trakcie działania 

algorytmu. 

ASD

LJ

S

Złożoność pamięciowa podobnie jak w przypadku złożoności czasowej jest określana 
jako funkcja rozmiaru danych n. Funkcja ta określa ilość zajętej pamięci podczas 
działania algorytmu, przy założeniu, że na każdą zmienną elementarną potrzebna jest 
jedna komórka pamięci. Zwykle ilość pamięci nie zależy od wartości danych, a tylko 
od ich rozmiaru. Dlatego też za złożoność pamięciową przyjmuje się złożoność
pesymistyczną. 

 

background image

 

32 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 

Złożoność pamięciowa

Max pciag(A,n,start,fin)
{

...
….
FOR (j:=1,2,…,n){

input(x);
act_sum=act_sum+x;

……

……

}
……

}

Złożoność pamięciowa algorytmu jest stała

O(1).

Jeśli pamięć jest stała względem rozmiaru danych n, to algorytm działa w miejscu (in 
place, in situ).

ASD

LJ

S

 

Złożoność pamięciowa

Metody obniżania złożoności pamięciowej.

 Wielokrotne obliczanie wartości,

 Implementacja struktur rozproszonych,

 Kompresja danych,

 Strategie przydziału pamięci.

ASD

LJ

S

 

background image

 

33 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 
 

Wielokrotne obliczanie wartości

Pamięć potrzebna do przechowywania danego obiektu może zmniejszyć się, jeśli 
nie  zapamiętamy  go,  a  zamiast  tego  będziemy  obliczać jego  wartość za  każdym 
razem, gdy będzie ona potrzebna. 
Dla  przykładu  tablicę liczb  pierwszych  można  zastąpić procedurą sprawdzającą, 
czy jakaś liczba naturalna jest liczbą pierwszą. 
Zamiast pamiętać cały obiekt, przechowujemy  jedynie program, który go generuje 
i wartość startową (generator), określającą ten konkretny obiekt. 

ASD

LJ

S

 

Stosowanie struktur rozproszonych

Różnorodne  tablice,  macierze  rzadkie  (

sprase

matrix

),  grafy  używane  w 

programach  są często  strukturami  rozproszonymi.  Do  ich  implementacji  można 
używać specjalnych struktur listowych o złożoności pamięciowej O(n), gdzie n jest 
liczbą elementów niezerowych.

ASD

LJ

S

 

background image

 

34 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 
 
 

Kompresja danych

Koncepcje  umożliwiające  ograniczenie  pamięci  przez  stosowanie  kompresji 
danych pochodzą z teorii informacji. 
Jeżeli  np.  elementy  macierzy  rzadkiej  przyjmują tylko  dwie  wartości,  to  możemy 
zapamiętać je w postaci upakowanej na bitach. 
Podobnie dwie cyfry dziesiętne a i b można  zapisać w  jednym  bajcie  za pomocą
liczby n=10a+b. 
Do odkodowania informacji służą wówczas dwie instrukcje:

a = n 

div

10

b = n 

mod

10

ASD

LJ

S

 

Strategie przydziału pamięci

Czasami  ilość dostępnej  pamięci  nie  jest  tak  ważna  jak  sposób  jej  wykorzystania. 
Do  optymalizacji  przydziału  pamięci  stosuje  się techniki:  dynamiczny  przydział
pamięci, rekordy zmiennej długości, odzyskiwanie pamięci, dzielenie pamięci.

ASD

LJ

S

Jeżeli dane są dwie macierze symetryczne A i B o rozmiarach nxn, przy czym obie 
mają zera na głównej przekątnej, to można przechowywać tylko macierz trójkątną
każdej z nich.  
Można zatem  pozwolić,  aby  obie  tablice  dzieliły  przestrzeń macierz  kwadratowej 
C, której jeden z narożnych fragmentów mialby postać:

0

B[1,2]

B[1,3]

A[3,1]

A[3,2]

0

A[2,1]

0

B[2,3]

C=

A[i,j] 

→ C[max(i,j), min(i,j)]

B[i,j] 

→ C[min(i,j), max(i,j)]