Numerische Methoden und Algorithmen in der Physik

Werbung
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Numerische Methoden und Algorithmen in der
Physik
Hartmut Stadie, Christian Autermann
06.11.2008
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
1/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
2/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Übersicht
Einführung
Literaturliste
Sortierung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
3/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Informationen
Material:
B. Stroustrup: The C++ Programming Language, 3rd
edition
http://www.mathematik.uni-marburg.de/∼cpp/
B. Stroustrup: C++ In-depth Series
A. Koenig, B. E. Moo: Accelerated C++
W. H. Press et al: Numerical Recipes, 3rd edition
T. H. Cormen et al: Introductions to Algorithms, 2nd edition
http://wwwiexp.desy.de/studium/lehre/numalg/
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
4/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Sortierung
Ein Beispiel aus der Praxis
Die CDF and DØ Experimente am Tevatron Beschleuniger
haben seit 2001 jeweils etwa 1010 Ereignisse aufgezeichnet
(eine Datenmenge von der Größenordnung Petabyte).
Eine wichtige Größe, sowohl zur Rekonstruktion der
Ereignisse, als auch für die Effizienz des Beschleunigers, ist
die exakte Lage der Wechselwirkung z0 .
Die Größe z0 möchte man z.B. in bezug auf die Zeit, die
Temperatur, Luminosität, etc untersuchen, d.h. sortieren.
Weitere Beispiele: Datenbanken, Google, ...
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
5/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Sortieralgorithmus: Insertion-Sort
Sortierung von Karten
Füge Karten nacheinander und sortiert ein
Solange bis alle Karten aufgenommen sind
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
6/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Insertion-Sort: Pseudo-Code
Aufgabe
Sortierung des folgendes Feldes A:
1
2
3
4
5
6
5
2
4
6
1
3
for j=1 bis Länge(A)
Schlüssel = A[j]
//Das Element an Position "j" wird in den schon
//sortierten Abschnitt 1..j-1 von A eingefügt
i = j-1
while i>0 und A[i]>Schlüssel
A[i+1] = A[i]
i = i-1
A[i+1] = Schlüssel
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
7/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Datenfelder
Datenstruktur zur Aufnahme mehrerer Variablen gleichen Typs.
Beispiele für Datenfelder in C++:
Das Array, z.B.
int MeinArray[6];
Der Vector der Standard Template Library (STL)
std::vector<int> MeinVector;
Die Map der STL
std::map<float,int> MeineMap;
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
8/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Übersicht
Einführung
Datenfelder
Das Array
Der STL vector
Die STL map
Sortieralgorithmen
Vergleich von Datenstrukturen
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
9/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Das Array
Das Array ist eine Menge von Elementen gleichen Typs
Funktioniert mit allen Typen
Sie sind im Speicher hintereinander abgelegt
Deklaration:
Typ Name [Größe];
Beispiele:
float A[10];
int
B[ 5] = {3, 1, 4, 1, 5};
int
C[ ] = {3, 1, 4, 1, 5, 9, 2, 6, 5};
C[0]
C[1]
C[2]
C[3]
C[4]
C[5]
C[6]
C[7]
C[8]
3
1
4
1
5
9
2
6
5
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
10/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Zugriff auf Arrays
Schreiben und Auslesen von Elementen eines Arrays.
#include <iostream>
//std::cout, std::endl
using namespace std;
int main(void)
{
float C[] = {3.0, 1.1, 4.2, 1.3, 5.4, 9.5, 2.6, 6.7, 5.8, 3.9};
int
Index;
float NeuerWert;
while ( true ) {
cout << "Index = ";
cin >> Index;
cout << "C[Index] = " << C[Index] << "
cin >> NeuerWert;
C[Index] = NeuerWert;
Neuer Wert = ";
}
}
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
11/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Zugriff auf Arrays
Schreiben und Auslesen von Elementen eines Arrays.
#include <iostream>
//std::cout, std::endl
using namespace std;
int main(void)
{
float C[] = {3.0, 1.1, 4.2, 1.3, 5.4, 9.5, 2.6, 6.7, 5.8, 3.9};
int
Index;
float NeuerWert;
Achtung: bug!
for (; true; ) {
cout << "Index = ";
cin >> Index;
if (Index<0 || Index>9) continue;
cout << "C[Index] = " << C[Index] << "
cin >> NeuerWert;
C[Index] = NeuerWert;
}
Neuer Wert = ";
}
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
12/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Vorteile von Arrays
Einfach
Schneller Zugriff
Nachteile von Arrays
Die Größe muss zum Zeitpunkt der Kompilation bekannt
sein (Workaround mit Zeigern existiert)
Die Größe ist fest und kann nicht verändert werden
Der Ort im Speicher eines Elementes ist fest durch den
Index bestimmt. Sortieren erfordert das Kopieren der
Elemente (×3).
Langsam für Element-Typen größer als int.
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
13/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Der STL vector
Deklaration
std::vector<Typ> Name;
Beispiel:
#include <vector>;
using std::vector;
vector<int> A;
//Library
//Der namespace std
//Deklaration
Der std::vector ist bei der Deklaration leer,
Elemente können bei der Deklaration übergeben werden, oder
zu Laufzeit des Programms gefüllt werden.
vector<int> A(2, 1);
A.push_back( 4 );
A.pop_back();
cout << A[0] << A.at(0);
//Inhalt von "A": 1 1
//Inhalt von "A": 1 1 4
//Inhalt von "A": 1 1
// 11
cout << A[5];
cout << A.at(5);
//segmentation fault: Programm Abbruch!
//Signal ’std::out_of_range’:
Programm Abbruch!
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
14/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Zugriff auf den std::vector
Der std::vector<int> A sei gefüllt mit 10 Elementen 1..10.
//Rückwertskompatibel zur Array-Syntax:
for (int i=0; i!=A.size(); ++i)
cout <<"A[i]=" <<A[i] <<endl;
//C++ Zugriff:
for (vector<int>::const_iterator it = A.begin(); it!=A.end(); ++it)
cout <<"A[i]" << *it <<endl;
Der Iterator it zeigt auf ein Element des vectors.
(*it) ist das Element. Der Operator “*” dereferenziert.
vector::begin() zeigt auf das erste Element,
vector::end() zeigt auf die Position hinter dem letzten
Element.
Mit einem const_iterator kann der vector nicht verändert
werden.
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
15/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
(Ausgewählte) Methoden des std::vector<>
(constructor)
(destructor)
operator=
Iterators:
begin
end
rbegin
rend
Capacity:
size
empty
Element access:
operator[]
at
front
back
Modifiers:
push_back
pop_back
insert
erase
clear
Construct vector
Vector destructor
Copy vector content
Return iterator to beginning
Return iterator to end
Return reverse iterator to reverse beginning
Return reverse iterator to reverse end
Return size
Test whether vector is empty
Access element
Access element
Access first element
Access last element
Add element at the end
Delete last element
Insert elements
Erase elements
Clear content
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
16/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Beispiel: Bestimmung des Median
Der Median ist das Element, welches eine Menge in zwei gleich
große Hälften teilt.
#include <iostream>
#include <vector>;
#include <algorithm>
using namespace std;
//std::sort
int main() {
vector<float> Menge;
float Zahl;
while (cin >> Zahl)
Menge.push_back( Zahl );
//Einlesen von Zahlen
sort(Menge.begin(), Menge.end()); //Eine Sortierfunktion
int Mitte = Menge.size()/2;
cout << "Median = "
<< (Menge.size()%2==0 ? (Menge[Mitte]+Menge[Mitte-1])/2.0
: Menge[Mitte])
<< endl;
}
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
17/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Die STL map
Deklaration
std::map<Typ1, Typ2> Name;
Beispiel:
#include <map>;
using std::map;
map<string, int> A;
//Library
//Der namespace std
//Deklaration
Die std::map ist bei der Deklaration leer,
Neue Elemente werden sortiert (in bezug auf das 1. Element)
eingefügt!
A["Christian"] = 1;
A["Hartmut"] = 2;
cout << A["Christian"];
cout << A[2];
cout << A["2"];
// 1
// Kompilationsfehler!
// 0
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
18/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Zugriff auf die std::map mittels des Schlüssels
std::map<Typ1, Typ2> Name;
Das erste Element ist der Schlüssel, der zweite der Wert. Der
Zugriff erfolgt durch den Schlüssel, der Schlüssel kann nicht
verändert werden!
Zugriff auf die std::map mittels Iteratoren
std::map<string, int> A;
Analog zum std:: vector gibt es verschiedene Iteratoren: Mit
einem “const_iterator” kann auch der Wert nicht verändert
werden.
for (map<string, int>::iterator it=A.begin(); it!=A.end(); ++it) {
cout << " A[" << it->first
<< "] = " << it->second << endl;
++(it->second);
}
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
19/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
(Ausgewählte) Methoden der std::map<>
Iterators:
begin
end
Capacity:
size
empty
Element access:
operator[]
Modifiers:
insert
erase
swap
clear
Observers:
key_comp
value_comp
Operations:
find
count
lower_bound
upper_bound
equal_range
Return iterator to beginning
Return iterator to end
Return size
Test whether vector is empty
Access element
Insert element
Erase elements
Swap content
Clear content
Return key comparison object
Return value comparison object
Get iterator to element
Count elements with a specific key
Return iterator to lower bound
Return iterator to upper bound
Get range of equal elements
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
20/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Beispiel: Zählen von Wörtern
Aufgabe: Einlesen einer beliebigen Anzahl an Wörtern,
Sortierte Ausgabe mit Anzahl der Vorkommnisse
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
21/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Beispiel: Zählen von Wörtern
#include <iostream>
#include <string>
#include <map>
using namespace std;
int main()
{
string s;
map<string, int> zaehler;
//Einlesen von Woertern, Zahlen, Buchstaben, ...
while (cin >> s)
++zaehler[s];
//Ausgeben der sortierten Woerter und ihrer Anzahl
for (map<string, int>::const_iterator it = zaehler.begin();
it != zaehler.end(); ++it) {
cout << it->first << "\t" << it->second << endl;
}
}
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
22/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Übersicht
Einführung
Datenfelder
Sortieralgorithmen
Übersicht
Quicksort
Heapsort
Vergleich von Datenstrukturen
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
23/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Übersicht
Eine der wichtigsten charakterisierenden Größen in bezug auf
Algorithmen ist das Laufzeitverhalten (siehe letzte Übung). Bei
großen Datenmengen ist ein Sortieralgorithmus mit einem
Laufzeitverhalten wie Insertionsort mit n2 inakzeptabel.
Die hier vorgestellten Algorithmen Quicksort und Heapsort
haben ein durchschnittliches Laufzeitverhalten auf unsortierten
Feldern wie n ln n, wobei optimierte Quicksort Algorithmen in
der Regel am schnellsten sind.
Im worst-case Szenario unterscheiden sich Quicksort und
Heapsort jedoch stark. Eine weitere charakterisierende Größe
von Sortieralgorithmen ist die Stabilität. Ein Algorithmus ist
stabil, wenn die relative Reihenfolge gleicher Elemente nicht
verändert wird (→ Übung).
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
24/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Quicksort
Der Quicksort Algorithmus wurde 1962 C. A. R. Hoare
entwickelt. Bei n zu sortierenden Elementen, benötigt der
Algorithmus im Durchschnitt O(n ln n) Vergleiche.
Wegen seiner strikten “Teile-und-Herrsche” Struktur lässt sich
Quicksort sehr einfach parallelisieren. Bei genügend vielen
Prozessoren ist die Laufzeit von der Ordnung O(n), oder sogar
noch besser.
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
25/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Quicksort Algorithmus
1
Wähle ein Pivot (Referenz) Element
2
Sortiere alle anderen Elemente bezüglich des
Pivot-Elementes in dem Feld: Ist ein Element kleiner als
der Pivot, dann verschiebe es links neben den Pivot. Ist es
größer dann verschiebe es nach rechts.
3
Die Position des Pivots wird sich nicht mehr ändern.
Teile und Herrsche: Die zwei Abschnitte links und rechts
des Pivots müssen noch (auf gleiche Art) sortiert werden.
Rufe den Algorithmus für den linken und den rechten
Abschnitt rekursiv auf!
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
26/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Quicksort Beispiel
1
2
3
4
5
6
7
8
3
8
7
2
4
5
1
6
1
2
3
4
5
6
7
8
2
1
3
8
7
4
5
6
1
2
3
4
5
6
7
8
1
2
3
7
4
5
6
8
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
27/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Quicksort Algorithmus: Pseudocode
Funktion quicksort(Feld A)
Feld Kleiner, Groesser
//Rekursionsabbruch:
if Laenge( A ) <= 1
return A
//Bestimme Pivot:
Pivot = A[0]
//Sortiere jedes Element entweder vor
//oder hinter den Pivot:
for each x in A
if x <= Pivot then
Kopiere x nach Kleiner
else
Kopiere x nach Groesser
return quicksort(Kleiner) + Pivot + quicksort(Groesser)
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
28/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Quicksort Algorithmus
Quicksort lässt sich in C++ recht einfach mit std::vector<>
programmieren, da die Länge der Vektoren nicht festgelegt sein
muss.
Tipp: Eine Funktion, die zwei std::vector<float> als Argument
übernimmt und (ohne die Reihenfolge zu ändern)
zusammengefügt zurück gibt
vector<float> Verbinde(const vector<float>& A,
const vector<float>& B)
{
vector<float> Ergebnis( B );
Ergebnis.insert( B.begin(), A.begin(), A.end() );
return Ergebnis;
}
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
29/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Heapsort
Heapsort Algorithmus
Die Heap-Struktur kann als binärer Baum verstanden werden.
Diese Baumstruktur spielt auch in vielen weiteren Algorithmen
eine wichtige Rolle. Die Tiefe des Heaps (Höhe des Baumes)
ist gegeben durch ln n.
Wie Insertionsort sortiert auch Heapsort ein Feld, ohne das
Elemente oft kopiert werden müssen: Die Anzahl der
Kopiervorgänge ist konstant.
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
30/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Der Heap
Für ein Element mit Index i berechnet sich
Vaterindex: p =abrunden(i/2)
Schnelle Berechnung: p = i 1
Index links: l = 2 · i
Schnelle Berechnung: l = i 1
Index rechts: r = 2 · i + 1
Schnelle Berechnung: r = (i 1)&1
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
31/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Für Heapsort werden Max-Heaps benutzt.
Ein Heap ist ein Max-Heap, wenn jedes Element A[i] an Index i
größer (mind. gleich) ist, als beide Tocher-Elemente, also
A[i] ≥max(A[l], A[r ]).
Pseudocode: Max-Heapify
Max-Heapifiziert den Heap an Index i, unter der Voraussetzung, dass beide
Tocher-Heaps Max-Heaps sind
MaxHeapify( A, i )
l = IndexLinks( i )
r = IndexRechts( i )
if l<=Groesse(A) und A[l]>A[i]
groesser = l
else
groesser = i
if r<=Groesse(A) und A[r]>A[l]
groesser = r
if groesser!=i
Tausche_Element A[i] und A[groesser]
MaxHeapify( A, groesser )
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
32/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Max-Heapify
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
33/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Konstruktion eines Max-Heap
Der Max-Heapify Algorithmus funktioniert für den Knoten i
unter der Voraussetzung, dass die Tochterknoten bereits
Max-Heaps sind.
Pseudocode um aus einem unsortierten Feld einen Max-Heap
zu konstruieren:
KonstruiereMaxHeap( A )
for i=Groesse(A)/2 bis 1
MaxHeapify( A, i )
Die Knoten mit Index Groesse(A)/2 bis Groesse(A) sind
bereits Max-Heaps mit Größe 1. (Es sind die “Blätter” des
Baumes.)
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
34/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Der Heapsort Algorithmus
Man kann sicher sagen, dass das Element an der Wurzel des
Heaps, also A[1] das größte Element ist, wenn der komplette
Heap ein Max-Heap ist.
Deshalb kann dieses Element A[1] mit dem letzten Element
A[N] vertauscht werden. Das verbleibende Feld A[1..(N − 1)]
muss neu MaxHeapified werden, dann kann der Schritt iterativ
wiederholt werden, bis das ganze Feld sortiert ist.
HeapSort( A )
KonstruiereMaxHeap( A )
for i=Groesse(A) bis 2
Tausche_Element A[i] und A[1]
MaxHeapify( A[1..i], 1)
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
35/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Heapsort
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
36/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Übersicht
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
STL Container Spezialisierung
Zeiger
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
37/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Containerimplementationen
verschiedene Container: vector; list; map
Laufzeitverhalten:
vector
list
queue
map
string
[]
const
O(log(n)
const
einfügen/löschen
O(n)+
const
const
O(log(n))+
O(n)+
Numerische Methoden und Algorithmen in der Physik
front
const
const
O(n)+
back
const+
const
iterator
random
Bi
const+
Bi
random
Christian Autermann
38/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Zeiger
Für Typ T: T* ist Zeiger auf Objekt von Typ T.
char c = ’a’;
char* p = &c;
*p = ’b’;
int *pi;
char** ppc;
int* ap[15];
int (*fp)(char*);
//Adresse von c
//Wert, auf den der Zeiger zeigt
//Zeiger auf int
//Zeiger auf Zeiger auf char
//Feld mit 15 Zeigern auf ints
//Zeiger auf Funktion mit char* als
//Argument und int* als Typ
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
39/ 40
Einführung
Datenfelder
Sortieralgorithmen
Vergleich von Datenstrukturen
Zeiger und Felder
Zeiger und Felder sind eng verwandt:
int v[]
int *pv
int *p2
int *p3
++pv;
=
=
=
=
{1,3,5,6};
v;
//Zeiger auf erstes Element
&v[0];
//gleich!
&v[1];
//Zeiger auf zweites Element
//pv zeigt nun auf zweites Element
p+1 erhöht die Adresse um size_of(T)
Numerische Methoden und Algorithmen in der Physik
Christian Autermann
40/ 40
Herunterladen