Przykładowe sprawozdanie

Transkrypt

Przykładowe sprawozdanie
Przykładowe sprawozdanie
Jan Pustelnik
30 marca 2007
Rozdział 1
Sformułowanie problemu
Tematem pracy jest porównanie wydajności trzech ”tradycyjnych” metod sortowania:
InsertionSort, SelectionSort i BubbleSort. Dla uproszczenia zakładamy tradycyjny
model kosztu obliczeniowego, w którym dana jest maszyna o stałym czasie wykonywania
operacji dodawania liczb całkowitych dowolnej długości. Parametrem zmiennym będzie
liczba elementów tablicy wejściowej, oznaczana dalej literą n.
Wszystkie trzy porównywane algorytmy charakteryzują się we wspomnianym powyżej modelu przeciętną złożonością obliczeniową O(n2 ), przy czym stały współczynnik
kryjący się za notacją O(·) jest różny dla wszystkich trzech metod.
Dla celów poniżej prezentowanych badań jako język implementacji wybrano ISO
C++, kompilacji dokonano kompilatorem gcc zaś architekturą dla której generowany
był kod jest architektura x86.
Rozdział 2
Krótki opis porównywanych metod
sortowania
Wszystkie metody będą prezentowane zgodnie z [2]. Założono istnienie dwóch funkcji:
exch i compexch, zdefiniowanych jak niżej:
1 // S e d g e w i c k ,
str .
242
template <typename Item>
void e x c h ( Item &A,
Item &B) {
Item t = A ;
A = B;
6
B = t;
}
template <typename Item>
void compexch ( Item &A,
11
if
Item &B) {
(B < A)
e x c h (A, B) ;
}
2.1
InsertionSort
Poniżej fragment kodu implementujący metodę sortowania przez wstawianie (ang. insertion sort) w języku C++. Metoda ta będzie uruchamiana przez większy fragment
kodu (tzw. sterownik - driver lub rusztowanie - scaffolding).
1 // S e d g e w i c k
s t r o n a 249
// w c i e c i a K&R
template <typename Item>
void i n s e r t i o n ( Item a [ ] ,
6
for ( int
i = r;
int l ,
int r ) {
i > 1 ; −−i )
compexch ( a [ i − 1 ] , a [ i ] ) ;
for ( int
int
i = l +2; i <= r ; ++i ) {
j = i;
Item v = a [ i ] ;
11
while ( v < a [ j − 1 ] ) {
a [ j ] = a [ j −1];
−−j ;
2.2. SELECTIONSORT
3
}
a[ j ] = v;
}
16
}
2.2
SelectionSort
Poniżej prezentowany jest fragment kodu implementujący w C++ metodę sortowania
przez wybór (ang. selection sort).
// S e d g e w i c k ,
str .
246
2 template <typename Item>
void
s e l e c t i o n ( Item a [ ] ,
for ( int
int l ,
int r ) {
i < r ; ++i ) {
i = l;
i n t min = i ;
for ( int
7
if
j = i + 1;
j <= r ; ++j )
( a [ j ] < a [ min ] )
min = j ;
e x c h ( a [ i ] , a [ min ] ) ;
}
}
2.3
BubbleSort
I wreszcie ostatni framgent kodu w C++ - implementacja metody sortowania bąbelkowego (ang. bubble sort). Ciekawą analizę tej metody sortowania wraz z propozycjami
zwiększenia wydajności prezentuje [1]
// S e d g e w i c k ,
str .
251
template <typename Item>
void b u b b l e ( Item a [ ] ,
4
for ( int
i = l;
for ( in
int l ,
int r ) {
i < r ; ++i )
j = r;
j > i ; −−j )
compexch ( a [ j − 1 ] , a [ j ] ) ;
}
Rozdział 3
Metodologia użyta w porównaniu
W porównaniu użyto dosyć prostej metodologii. Porównano wybrane metody sortowania
dla danych wejściowych o zmiennym rozmiarze n, gdzie n zmieniało się w zakresie od 0
do 2 · 105 , przy czym użyto dwóch podzakresów: od 0 do 2 · 104 , co 1000 (1 · 103 ) i od 0 do
2 · 105 , co 10000 (1 · 104 ). Zastosowano również trzy różne rodzaje zbiorów wejściowych:
zbiór ”losowy” (rozkład jednostajny), zbiór odwrotnie uporządkowany (uporządkowany
malejąco) i zbiór uporządkowany (uporządkowany rosnąco).
Dla każdego rozmiaru n powtórzono pomiar 10-krotnie w celu wyeliminowania przypadkowych zaburzeń. Jest to szczególnie ważne dla danych losowych.
Rozdział 4
Kilka słów o użytych narzędziach
Programy kompilowane były kompilatorem gcc z użyciem opcji -O2:
$ gcc -v
Using built-in specs.
Target: i486-linux-gnu
...
gcc version 4.0.3 (Ubuntu 4.0.3-1ubuntu5)
Platformą wykonania był procesor Intel Dothan (Pentium M) 1.6 GHz, komputer
zaopatrzony był w 1 GB pamięci RAM.
Sprawozdanie przygotowano przy użyciu narzędzia LATEX, wykresy przygotowano za
pomocą narzędzia gnuplot.
Rozdział 5
Wyniki
Na początek porównano wyniki dla róznych algorytmów sortowania, dla tego samego
typu danych wejściowych o ”małym” rozmiarze.
Następnie przeanalizowano jak zachowuje się każdy z algorytmów dla różnego rodzaju danych wejściowych, znów o ”małym” rozmiarze.
25
"insertion_random.dat"
"selection_random.dat"
"bubble_random.dat"
20
15
10
5
0
0
5000
10000
15000
20000
Rysunek 5.1: Dane losowe, trzy rózne algorytmy sortowania
7
10
"insertion_ordered.dat"
"selection_ordered.dat"
"bubble_ordered.dat"
9
8
7
6
5
4
3
2
1
0
0
5000
10000
15000
20000
Rysunek 5.2: Dane posortowane, trzy rózne algorytmy sortowania
20
"insertion_back.dat"
"selection_back.dat"
"bubble_back.dat"
18
16
14
12
10
8
6
4
2
0
0
5000
10000
15000
20000
Rysunek 5.3: Dane posortowane malejąco (odwrotnie), trzy rózne algorytmy sortowania
8
25
"bubble_random.dat"
"bubble_ordered.dat"
"bubble_back.dat"
20
15
10
5
0
0
5000
10000
15000
20000
Rysunek 5.4: Algorytm BubbleSort, różne dane
6
"insertion_random.dat"
"insertion_ordered.dat"
"insertion_back.dat"
5
4
3
2
1
0
0
5000
10000
15000
Rysunek 5.5: Algorytm InsertionSort, różne dane
20000
9
6
"selection_random.dat"
"selection_ordered.dat"
"selection_back.dat"
5
4
3
2
1
0
0
5000
10000
15000
Rysunek 5.6: Algorytm SelectionSort, różne dane
20000
Rozdział 6
Podsumowanie i wnioski
Z zamieszczonych powyżej wykresów wyraźnie widać, że:
• Najwolniejszym z wszystkich algorytmów jest BubbleSort, najszybszym InsertionSort,
przy czym w miarę wzrostu rozmiaru danych róznica między SelectionSort a
InsertionSort rośnie zdecydowanie wolniej niż między BubbleSort a pozostałymi dwoma algorytmami
• BubbleSort najszybciej sortuje dane już posortowane (choć i tak zajmuje to sporo
czasu), najwolniej dane uporządkowane losowo
• InsertionSort najlepiej radzi sobie z danymi uporządkowanymi - czas działania w tym wypadku wynosi praktycznie zero, najgorzej (co może dziwić jeśli nie
przeczytaliśmy uważnie opisu algorytmu) - dane posortowane odwrotnie.
• dla SelectionSorta sposób uporządkowania danych nie ma znaczenia
I od razu można sformułować pewną ogólną obserwację: nie należy raczej używać BubbleSorta
(przynajmniej nie w podanej wyżej postaci), należy za to stosować InsertionSort (chyba, że mamy do dyspozycji coś lepszego), SelectionSort będzie interesujący, gdy ważnym kryterium będzie brak wrażliwości na rozkład danych (np. systemy czasu rzeczywistego!).
Powyższe obserwacje warto byłoby potwierdzić próbą dla większych n-ów, ale już nie
starczyło mi czasu - postaram się to zrobić w przyszłym tygodniu.
Bibliografia
[1] Bentley, J., “Perełki oprogramowania ”, WNT, Warszawa, rok nieznany
[2] Sedgewick, R., “Algorytmy w C++ ”, ReadMe, Warszawa, 1999

Podobne dokumenty