Am 27. April 2011 referiert Informatik-Student Marcus Riemer zu seiner Evaluierung der C++-Algorithmenbibliothek LEDA. Der Vortrag startet um 17 Uhr in Hörsaal 5.
Die Algorithmenbibliothek LEDA (Library of Efficient Data types and Algorithms) entstand am Max-Planck-Institut für Informatik in Saarbrücken unter der Leitung von Prof. Kurt Mehlhorn. Sie wird seit Jahren kommerziell vertrieben. Der Referent studiert an der FH Wedel Informatik und hat mehrjährige C++-Erfahrung. Er führte eine ausführliche Evaluierung durch und vergleicht die Ergebnisse mit der C++-Standardbibliothek und der Open-Source-Bibliothek Boost.
2. Vortrag ”Evaluierung von LEDA”
Fragen gerne sofort stellen
Lieber mehr als weniger
Bei Verweisen kann grunds¨tzlich gut gefragt werden
a
Vorausgesetzt
Teil ”Graphentheorie” der Vorlesung ”Diskrete Mathematik”
Grundlegende Kenntnisse der Programmierung
Hilfreich
Kenntnisse der objektorientierten Programmierung
Erfahrung mit C++
Material zum Vortrag
Diese Pr¨sentation
a
Codebeispiele
http://stud.fh-wedel.de/~inf8803/Seminar
3. Ablauf und Ziele
¨
Ein Uberblick uber LEDA
¨
Historie
Komponenten
Vergleich der Graphenfunktionalit¨t von LEDA und Boost
a
Unterschiede und Gemeinsamkeiten in der Datenstruktur
¨
Uberblick uber Algorithmen und Performance
¨
Kurze, beispielhafte L¨sung Implementierung eines Netzplans
o
Fazit und Diskussion
Gr¨nde f¨r den Einsatz von LEDA
u u
M¨gliche Einsatzgebiete
o
4. Gliederung
LEDA
¨
Uberblick
Numerik
Container
Geometrie
Speichermanagement
Graphen
Bewertung
N¨here Erl¨uterungen
a a
5. C++ damals
Zur Zeit der initialen LEDA Entwicklung (um 1990) war der
C++ ’Standard’ nur theoretisch portabel
Entwicklung von C++ begann 1979
Erstmalige ”ernsthafte” Verwendung von C++ innerhalb des
entwickelnden Umfeldes etwa 1983
Ver¨ffentlichung des Buches ”The C++ Programming
o
Language” 1985
Einf¨hrung von Templates in den sp¨ten 80ern
u a
Standarisierungsprozess begann 1987 durch das ANSII
→ ISO/IEC 14882:1998 (oder informell: C++ 98)
Standard Template Library (STL) damals standarisiert in Form
einer Sammlung von Headern
Art der Implementierung selten festgelegt
Verschiedene Standardbibliotheken je Compiler
Zudem subtile Unterschiede zwischen Compilern
bzw. brachiale Unterschiede bei Templates Was sind Templates?
6. Entstehung von LEDA
Entstanden als Reaktion auf permanente
Re-Implementierungen von bekannten Algorithmen und
Datenstrukturen ...
... die zudem nicht immer fehlerfrei waren.
Großer Zeitverlust → Langsamerer Fortschritt
Vier Designziele
Ease of use
Extensibility
Correctness 1
Efficiency
Heute kommerzieller Vertrieb
Kostenlose Version ohne Algorithmen, nur Datentypen
Professional Edition und Research Edition
Mit oder ohne Quellcode
Kommerzielle Nutzung nur in der Professional Edition
1
Siehe: Vortrag ’Certifying Algorithms’, Achenbach, WS2010, FH Wedel
7. Dokumentation
LEDA Buch
ISBN-13: 978-0521563291, vergriffen
Auch zum Download, eine Postscript Datei je Kapitel
http://www.mpi-inf.mpg.de/~mehlhorn/LEDAbook.html
Keine aktuelle Auflage vorhanden
Weiterhin eine zuverl¨ssige Quelle, gibt den Umfang von LEDA
a
jedoch nicht vollst¨ndig wieder
a
LEDA Manual
http://www.algorithmic-solutions.info/leda_manual/
Klassische API Dokumentation im Stile von Doxygen
LEDA Guide
http://www.algorithmic-solutions.info/leda_guide/
¨
Uberblick uber API mit h¨herem Anteil an Beispielen
¨ o
Verlinkt auf Manual
8. Dokumentation
Inoffizielles LEDA Tutorial von Joachim Ziegler
http://www.leda-tutorial.org/en/unofficial/
Praktische Einf¨hrung aus Anwendersicht
u
Demos
Kommen zusammen mit der Bibliothek
Sehr einfach kompilierbar
Oft verquickt mit visueller Darstellung
9. Umfang von LEDA
Numerik Graphen
Real, Complex, Rational Algorithmen
Matrizen & Vektoren Graph Datenstruktur
sowie Operationen der Geometrie
linearen Algebra
Algorithmen
Numerische Analysis f¨r
u
Spezielle Container
Extremstellen, Integration
und Nullstellen Verlustfreie Kompression
Algorithmen
Container
Auswahl ¨hnlich der STL
a Kryptografie
Optimiert f¨r kleine
u Symmetrische Verfahren
Elemente
Grundlage f¨r viele
u GUI
Algorithmen Speichermanager
10. Zahldatentypen
Sehr einfache Funktion
f (x) = x
Wird durch normale
Fließkomma Datentypen
statisch diskretisiert
4 byte float mit 7-8
signifikanten Stellen
Treppeneffekt
LEDA Typen mit theoretisch
beliebig hohen Au߬sung
o
Spezielle Konstanten f¨r
u
z.B. π oder e
11. Zahldatentypen
Implementierung der Zahlenr¨ume N, Q, R
a
Fließkommadatentyp mit erh¨hter Genauigkeit
o
Matrizen und Vektoren als Basis f¨r geometrische Probleme
u
Grundlegende Operationen mit Matrizen
integer_matrix matrix (3 ,3);
integer_matrix result (3 ,3);
integer d = determinant ( M ); // Determinante
integer r = rank ( M ); // Rang
result = transpose ( matrix ); // Transponieren
Fr¨her: Funktionen zum L¨sen von linearen Gleichungssystemen
u o
Kein Spezialgebiet und daher mit der kommerziellen Edition
aufgegeben → lieber Funktionalit¨t streichen, als
a
m¨glicherweise suboptimal zu Implementieren
o
Im Buch noch Verweise auf diese Funktionen
12. Numerische Analysis
Grundlegende Operationen
// Function to analyze
double f ( double x )
{
return ( pow (x , 2) * log ( x ) - 1);
}
// xmin passed by reference
double ymin , xmin ;
ymin = mi nimize _funct ion (f , xmin );
// Compute root between 0.5 and 2.5
double zero = zero_of_function (f , 0.5 , 2.5);
Berechnet Extrem- und Nullstellen
14. Container
LEDA trennt strikt zwischen Interface und Implementierung
Interfaces beschreiben ubliche Operationen und geben
¨
Laufzeitgarantien
Werden durch Vererbungen implementiert
Blick in die Headerfiles: incl/LEDA/core/
impl/ab_tree.h
impl/avl_tree.h
impl/...
growing_array.h
list.h
...
Beispielhafte ”Abweichungen”
Dynamisches Array intern ein ab_tree
B¨ume keine oberste Abstraktionsebene, Implementierung z.B.
a
auch durch Skiplists denkbar
15. Sequenzielle Container
Vergleich der Container in STL und LEDA
Container LEDA STL
Array leda::array<T> 1
String leda::string std::string,std::wstring
Dynamic Array 2 std::vector<T>
Stack leda::stack<T> std::stack<T>
Queue leda::queue<T> std::queue<T>
Priority Queues leda::p_queue<P,T> 3 std::priority_queue<T>
Set leda::set<T> std::set<T>
List leda::list<T> std::list<T>
Tupel Zwei- bis Viertupel std::pair<K,V>
LEDA bietet Implementierungen f¨r g¨ngige sequenzielle
u a
Container der STL
... diese sind jedoch keine ”drop-in replacements”
1
Kommender C++ Standard, siehe auch Boost
2
Hier im Sinne eines zu C kompatiblen Arrays ohne ’L¨cken’ im Speicher
u
3
Getrennte Typen f¨r Priorit¨t und Objekt
u a
16. Assoziative Container
STL
std::map<K,V> und LEDA
std::multimap<K,V> 1 d_array<K,V>
Strenge schwache Verlangt lineare Ordnung
Ordnungsrelation Momentan ein ab-Baum
¨
Ublicherweise ein h_array<K,V>
Bin¨rbaum
a
Hashed
→ Kein unsortierter Assoziativer Unsortiert
Container Verlangt Hashfunktion
map<K,V>
K muss Zeiger, Handle
oder Integer sein
Entfernen nicht m¨glich
o
Unsortiert
1
”multi”Container erlauben identische Schl¨ssel
u
17. Weitere LEDA Container
Integer Sets
Mengen f¨r Ganzzahlen
u
Alle ublichen Mengenoperationen
¨
Im Gegensatz zu std::bitset<n>
Gr¨ßen¨nderungen zur Laufzeit
o a
Mehr Bits als (sizeof(unsigned long) * 8)
Partitionen
same_block(p,q), union_blocks(p,q)
¨
Kein Aquivalenter Container in der STL
B¨ume
a
dynamic_trees und tree_collection
Unterschied ist der ”Ort” der Gewichtung
Kantengewichtung → dynamic_trees
Knotengewichtung → tree_collection
18. Performancevergleich
Einige Hinweise zum Performancevergleich
Der Benchmark entstammt den LEDA Demos und wurde nicht
angepasst
Es ist ein purer Performance Benchmark, keine Abbildung eines
konkreten Anwendungsszenarios
Jeder Test wurde mit 5.000.000 Elementen durchgef¨hrt
u
Eingesetzte Hardware
Intel(R) Core(TM) i5 CPU 750 @ 2.67GHz
6 GB Arbeitsspeicher
Softwarekonfiguration
OpenSuSE 11.3
g++ (SUSE Linux) 4.5.0
Windows 7
Microsoft (R) C/C++ Optimizing Compiler Version
15.00.30729.01 for x64 (Visual Studio 2008)
25. Geometrische Probleme mit LEDA
Alle zweidimensionalen Alle dreidimensionalen
Datentypen implementiert Datentypen implementiert
f¨r double, Q und R
u f¨r double und R
u
Punkt Punkt
Segment Segment, Strahl, Linie
Verbindung zweier Punkte, Ebene
finite L¨nge
a
Sph¨re
a
Strahl Simplex
Punkt und Richtung,
unbegrenzte L¨nge
a
Linie
Gerade durch zwei Punkte,
finite L¨nge
a
Kreis
Polygon
Dreieck
Rechteck
26. Geometrische Probleme mit LEDA
Im Zweidimensionalen noch weitere Datentypen
d2_dictionary<K1,K2,I>
Zweidimensonales Dictionary
Zuordnung von Punkten zu Daten
POINT_SET f¨r double, Q und R
u
Planarer, bidirektionaler Graph in Gestalt einer Delaunay
Triangualation
Bietet alle f¨r konstante Graphen m¨glichen Operationen
u o
Konstruktion durch einen Graphen oder eine Liste von Punkten
POINT_LOCATOR f¨r double, Q und R
u
Zur schnellen Suche von Punkten in Delaunay Triangulationen
27. Geometrische Probleme mit LEDA
Im Zweidimensionalen noch weitere Datentypen
interval_set<I>
insert(double x, double y, const I& i)
lookup(double x, double y)
segment_set und rat_segment_set
Menge von parallelen Segmenten
Schnelle Berechnung von Schnittpunkten
subdivision<I>
Planarer Graph in einer zweidimensionalen Ebene
Kanten sind ausschließlich gerade Linien
Schnelles auffinden von Punkten durch einen partiell
persistenten Suchbaum
28. Geometrische Probleme mit LEDA
Im Zweidimensionalen Im Dreidimensionalen
Affine Transformationen Algorithmen
Algorithmen Konvexe H¨lle
u
Konvexe H¨lle
u Triangulation auf Basis
Triangulation auf Basis von Graphen
von Graphen Voronoi Diagramme
Minkowski Summe und
Differenz
Voronoi Diagramme
Ausf¨hrliche Beschreibung der Implementierung im Buch
u
29. Speichermanagement von LEDA
Implementierung der Operatoren new und delete
new allokiert nicht bei jedem Aufruf tats¨chlich Speicher,
a
sondern bedient sich an einem pre-allokierten Pool
delete stellt Speicher wieder dem Pool zur Verf¨gung
u
Daher weniger Aufrufe der betriebssystemeigenen
Speicherfunktionen
Nutzung des RAII Prinzips Was ist RAII?
Vermeidung von Speicherlecks
Bei LEDA als ’Garbage Collection’ bezeichnet, jedoch nicht mit
z.B. Java oder C# vergleichbar!
30. Speichermanagement von LEDA
Benutzerdefinierte Klassen und LEDA Memory Management
class ImportantData
{
private :
double a ,b , c ;
unsigned int d ,e , f ;
/*
... More important data ...
*/
public :
/*
... Important functionality ...
*/
// " override " new and delete
LEDA_MEMORY ( ImportantData );
}
31. Gliederung
LEDA
Graphen
Datenstruktur
Algorithmen
Performance
Bewertung
N¨here Erl¨uterungen
a a
32. Graphen in LEDA und boost
Die Datenstruktur f¨r Graphen
u
Gemeinsamkeiten
Unterschiede
Einfache Beispiele
¨
High-Level Ubersicht uber Algorithmen
¨
Wenn wir Zeit haben: Beispielhafte Implementierung eines Netzplans
Bewertung
33. Gemeinsamkeiten
Templateklasse mit beliebigen Typen f¨r Knoten und Kanten
u
Daher Annotationen f¨r bestimmte Algorithmen notwendig
u
Position
Farbe
Gewicht
Parametrisierte Graphen erm¨glichen Zugriff auf Knoten und
o
Kanten via operator []
Eigene Indextypen f¨r Knoten und Kanten
u
Mehrere logische Sichten
Schnittstellen um die Daten effizient f¨r ”bekannte” Aufgaben
u
bereitzustellen
Algorithmen setzen auf diese Sichten auf
34. LEDA
Ein zentraler Datentyp GRAPH
Intern eine Adjazenzliste
Typisierbar
Limitiert auf 10.000 Knoten
Unterscheidung von gerichteten und ungerichteten Graphen
Standardm¨ßig gerichtet, ungerichtet ist UGRAPH
a
Konvertierung m¨glich via Graph::make_undirected() und
o
Graph::make_directed()
F¨r schnelle, lesende Zugriffe: static_graph
u
Keine Unterteilung nach Eigenschaften
Zentrale Methoden
node GRAPH::new_node()
erstellt im Graphen einen Knoten
edge GRAPH::new_edge(node, node)
erstellt im Graphen eine Kante zwischen den gegebenen Knoten
35. LEDA
Einfacher Graph mit LEDA
graph G ;
node v0 = G . new_node ();
node v1 = G . new_node ();
node v2 = G . new_node ();
node v3 = G . new_node ();
edge e0 = G . new_edge ( v0 , v1 );
edge e1 = G . new_edge ( v0 , v2 );
edge e2 = G . new_edge ( v1 , v2 );
edge e3 = G . new_edge ( v1 , v3 );
Erzeugt den Graph rechts
36. LEDA
Typisierter Graph mit LEDA
GRAPH < string , int > G ;
// Creation as before
// vN is a vertex
G [ v0 ] = " Hamburg " ;
G [ v1 ] = " Pinneberg " ;
G [ v2 ] = " Wedel " ;
G [ v3 ] = " Appen " ;
// eN is a edge
G [ e0 ] = 5;
G [ e1 ] = 6;
G [ e2 ] = 10;
G [ e3 ] = 4;
Erzeugt den Graph rechts
37. LEDA - Zugriff
Iteration mit Makros
¨
Uber Graphen
forall_nodes, forall_rev_nodes
forall_edges, forall_rev_edges
¨
Uber Knoten
forall_adj_edges
forall_out_edges, forall_in_edges,
forall_inout_edges
Iteration mit Iteratoren
Typsicher
Mehr Kontroller uber Iteration
¨
Implementierung von STL ¨hnlichen Iteratoren
a
38. LEDA - Zugriff
”intelligente” Zugriffsverfahren
GIT_BFS und GIT_DFS
Topological Sort – GIT_TOPOSORT
Strongly Connected Components – GIT_SCC
Dijkstra – GIT_DIJKSTRA
Zugriff uber spezielle Container f¨r Knoten und Kanten
¨ u
node_array, f¨r statische Graphen
u
node_map
node_list, node_slist
node_pq (Priority Queue)
node_partition Beispiel Kruskal
Zugriff nach Erstellung eines beliebigen Graphen
39. Boost Graph Library
Teil des Boost Projektes
Grundlage f¨r die ”Technical Reports” des C++
u
Standarisierungskomitees
Steht unter der Boost Software License
Keine Beschr¨nkung f¨r die Art der Nutzung
a u
Kein Copyleft
Fokus auf Erweiterbarkeit und Anpassbarkeit
Keine vorgeschriebe Datenstruktur
Flexible ”Graph Adaptors”
Einfache Erweiterung durch eigene Visitors
Intensive Nutzung von Templates / Concepts, potenziell
ungewohnt
”Header Only” Library, kein externes Linken notwendig
40. Boost Graph Library
Eigenschaften von
Graphen und ihre
interne Darstellung
zun¨chst getrennt
a
Algorithmen
arbeiten nur mit
Eigenschaften
Validierung
w¨hrend der
a
Kompilierung
Eigenschaften von Graphen bei Boost
41. Boost Graph Library
IncidenceGraph
Schneller Zugriff auf ausgehende Kanten von Knoten
source(edge, graph), target(edge, graph) und
out_edges(vertex, graph) in Θ(1)
AdjacencyGraph
Schneller Zugriff auf benachbarte Knoten eines Knotens (ohne
Ber¨cksichtigung der Kanten)
u
adjacent_vertices(vertex, graph ) in Θ(1)
VertexListGraph
Effiziente Iteration uber Knoten
¨
vertices(graph) in Θ(1)
EdgeListGraph
Effiziente Iteration uber Kanten
¨
source(edge, graph), target(edge, graph) und
edges(graph) in Θ(1)
42. Boost Graph Library
MutableGraph
Kann nach Konstruktion ver¨ndert werden
a
add_edge(source, target, graph),
remove_edge(source, target, graph) und
remove_edge(edge, graph)
add_vertex(graph) und remove_vertex(vertex, graph)
PropertyGraph
Unterst¨tzt im Prinzip beliebige Annotationen zu Knoten und
u
Kanten
→ Implementierungen von Graphen m¨ssen nur die als relevant
u
erachteten Interfaces bereitstellen
44. Boost Graph Library
Untypisierter Graph mit boost
// C r e a t i n g t h e a p p r o p r i a t e t y p e s
typedef b o o s t : : a d j a c e n c y l i s t <b o o s t : : vecS , b o o s t : : vecS ,
boost : : directedS > Graph ;
typedef b o o s t : : g r a p h t r a i t s <Graph > : : v e r t e x d e s c r i p t o r V e r t e x ;
typedef b o o s t : : g r a p h t r a i t s <Graph > : : e d g e d e s c r i p t o r Edge ;
// I n s t a n t i n a t e
Graph G ;
// Adding V e r t i c e s
V e r t e x v0 = b o o s t : : a d d v e r t e x (G ) ;
V e r t e x v1 = b o o s t : : a d d v e r t e x (G ) ;
V e r t e x v2 = b o o s t : : a d d v e r t e x (G ) ;
V e r t e x v3 = b o o s t : : a d d v e r t e x (G ) ;
// Adding Edges
Edge e1 , e2 , e3 , e4 ;
bool n e w V e r t e x ; // t r u e i f new e d g e was c r e a t e d , u n u s e d h e r e
// b o o s t : : t i e ( ) a s a c o n v e n i e n c e f u n c t i o n t o a s s i g n t u p l e s
b o o s t : : t i e ( e1 , n e w V e r t e x ) = b o o s t : : a d d e d g e ( v0 , v1 , G ) ;
b o o s t : : t i e ( e2 , n e w V e r t e x ) = b o o s t : : a d d e d g e ( v0 , v2 , G ) ;
b o o s t : : t i e ( e3 , n e w V e r t e x ) = b o o s t : : a d d e d g e ( v1 , v2 , G ) ;
b o o s t : : t i e ( e4 , n e w V e r t e x ) = b o o s t : : a d d e d g e ( v1 , v3 , G ) ;
45. Boost Graph Library
Typisierter Graph mit boost
// C r e a t i n g t h e a p p r o p r i a t e t y p e s
typedef b o o s t : : a d j a c e n c y l i s t <b o o s t : : vecS , b o o s t : : vecS ,
boost : : directedS ,
s t d : : s t r i n g , int> Graph ;
typedef b o o s t : : g r a p h t r a i t s <Graph > : : v e r t e x d e s c r i p t o r Vertex ;
typedef b o o s t : : g r a p h t r a i t s <Graph > : : e d g e d e s c r i p t o r Edge ;
// I n s t a n t i n a t e
Graph G ;
// C r e a t i o n a s b e f o r e
// vN i s a v e r t e x
G [ v0 ] = " Hamburg " ;
G [ v1 ] = " Pinneberg " ;
G [ v2 ] = " Wedel " ;
G [ v3 ] = " Appen " ;
// eN is a edge
G [ e0 ] = 5;
G [ e1 ] = 6;
G [ e2 ] = 10;
G [ e3 ] = 4;
46. Boost Graph Library
Boost Graph Adaptors
Legen eine weitere logische Sicht uber einen bestehenden
¨
Graphen
subgraph erlaubt die logische Unterteilung eines Graphen
reverse_graph vertauscht eingehende und ausgehende Kanten
bei einem bidirektionalen Graphen
filtered_graph erh¨lt ein Pr¨dikat und erlaubt nur Zugriff
a a
auf Knoten oder Kanten die dieses Pr¨dikat erf¨llen
a u
”Wrappen” andere Datenstrukturen in ein Boost Interface
edge_list modeliert einen EdgeListGraph f¨r Arrays aus
u
Paaren
Undokumentiert: std::vector als VertexListGraph
Undokumentiert: Matrix als Graph
Undokumentiert: LEDA Graph (erlaubt die Verwendung von
boost Algorithmen auf einem Leda Graphen)
Undokumentiert: Stanford GraphBase
47. Boost Graph Library
Visitors iterieren nach einem bestimmten Schema uber
¨
Graphen und nutzen Callbacks (genauer Funktoren)
Event Visitor
DFS und BFS Visitors
Dijkstra, A* und Bellman Ford Visitors
Planar Face Visitor
TSP Tour Visitor
48. ¨
Uberblick Algorithmen
¨
Diese Ubersichten enthalten keine Wertung uber die Qualit¨t
¨ a
der Implementierungen und sind nicht zwingend vollst¨ndig!
a
Implementierungen ”bekannter” Algorithmen wie z.B:
K¨rzeste Wege (single source) mit Dijkstra oder Bellman-Ford
u
K¨rzeste Wege f¨r alle Paare
u u
Spannende B¨ume / W¨lder mit Kruskal oder Prim
a a
Maximum-Flow mit z.B. Edmonds Karp
Allgemeines Layouting
Minimale Schnitte mit Stoer-Wagner
Tests auf Planarit¨t
a
49. ¨
Uberblick Algorithmen
Zus¨tzlich bei LEDA
a Zus¨tzlich bei Boost
a
Euler-Touren A* Algorithmus
Morphismen Resourcenbeschr¨nkte Suche
a
Geometrischer Schwerpunkt Sortierung d¨nn besetzter
u
(Triangulation) Matrizen
Korrektheitsnachweise f¨r
u Umfangreichere Layouting
viele Algorithmen Algorithmen
Fazit
Boost etwas ”praktischer” aufgestellt als LEDA ...
... oder LEDA etwas ”mathematischer” aufgestellt als Boost?
50. Performance
Allgemein
Leider keine Zeit f¨r umfangreiches Benchmarking
u
Daher nur einige ”lose” Beobachtungen
Performance der Algorithmen
Kein nennenswerter Unterschied bei
K¨rzeste Wege mit Dijkstra
u
Topologischer Sortierung
Drastische Perfomancegewinne bei ”statischen” Graphen
Speziell LEDA erm¨glicht sehr schnelles kopieren in einen
o
statischen Graphen
53. Allgemeine Bewertung
Mit Bezug auf C++
Bildet einen ”Mikrokosmos”
Alle grundlegenden Datentypen vorhanden → Einarbeitung in
weitere Libraries (inklusive der STL) nur selten n¨tig
o
Verzicht auf Nutzung von modernen C++ Aspekten
Gew¨hnungsbed¨rftiger Umgang mit Templates (*.t Dateien)
o u
Vorhandene, aber sp¨rliche Interoperabilit¨t im Sinne der STL
a a
Komplett auf make ausgerichtetes Buildsystem
Fazit
Angenehm f¨r Leute die keinen vertieften Umgang mit C++
u
hatten, da auf sehr spezielle Techniken verzichtet wird
Im Umkehrschluss f¨r Leute die auf modernere Aspekte von
u
C++ setzen ungewohnt
Hohe Qualit¨t der Algorithmen und Datenstrukturen
a
54. LEDA gemessen an den vier Designzielen
Ease of Use
LEDA l¨sst sich in der Tat auch nach kurzer
a
Eingew¨hnungszeit gut benutzen
o
Die Dokumentation ist alles in allem sehr hilfreich
Extensibility
Quellcode Lizenz f¨r eigene Erweiterung notwendig
u
Speziell bei Templateklassen allgemein kritisch
Correctness
”Certifying Algorithms” eine sehr gute Grundlage
Efficiency
Wesentlich effizienter als STL
In meinen Augen LEDAs st¨rkstes Argument
a
Kombination aus Effizienz und Korrektheit f¨r eine C++
u
Bibliothek einzigartig
55. M¨gliche Einsatzfelder von LEDA
o
LEDA in Konkurenz zu mathematischer Standardsoftware?
Schwerer zug¨nglich, aber sehr flexibel
a
LEDA in der Spieleentwicklung
Sehr effiziente Algorithmen, die Spieleentwickler oft
stiefm¨tterlich behandeln
u
Triangulation + Wegfindung = Einfache Wegfindung in
dreidimensionalen Welten?
Nutzung der hocheffizienten Datenstrukturen
Leider nur sehr begrenzt STL kompatibel
Gute grundlage f¨r Algorithmen
u
Kostenlose Version nicht mit voller Effizienz
... Ideen aus dem Plenum?
56. Weitere Themen?
M¨gliche Themen f¨r weitere Vortr¨ge
o u a
Graphen
Explizite Vergleiche einzelner Algorithmen mit der Boost Graph
Library
Weitere Teilbereiche von LEDA
Geometrie (vermutlich am Spannendsten ;-) )
Kryptographie
Kompression
Sehr offene und gute Zusammenarbeit mit dem LEDA Team!
58. Was sind Templates? Zur¨ck
u
Mechanismus f¨r Programmierung unabh¨ngig von Datentypen
u a
ohne Aufgabe von Sicherheiten zur Kompilierungszeit
Sollten Datentypen wie void* (C) oder variant(Pascal)
uber߬ssig machen
¨ u
¨
Starke Ahnlichkeiten mit generics in JAVA oder C#
Aber durch das fehlen einer VM v¨llig anders implementiert
o
(”verzuckertes define”)
Auch heute nur von einem Compiler (Comeau) komplett
unterst¨tzt
u
59. Was sind Templates? Zur¨ck
u
Typische Nutzung von Templates
// Works for every T with a " Name " method
// that returns something useful for operator +
int addNames <T >( T first , T second )
{
return first . Name () + second . Name ();
}
struct Person { std :: string Name (); };
struct Animal { std :: string Name (); };
Person p1 , p2 ;
Animal a1 , a2 ;
addNames < Person >( p1 , p2 );
addNames < Animal >( a1 , a2 );
¨
Ahnlich wie in Java oder C#
60. Was sind Templates? Zur¨ck
u
Rekursive Templates
template < unsigned int N >
struct product
{
static unsigned int const VALUE =
N * product < N - 1 >:: VALUE ;
};
template <>
struct product <1 >
{
static unsigned int const VALUE = 1;
};
// Usage :
unsigned int const p5 = product <5 >:: VALUE ;
Unm¨glich mit Java oder C#
o
61. Was ist RAII? Zur¨ck
u
Beispiel f¨r Code ohne RAII
u
bool sol v e Ha l t in g P ro b l em ( Device d )
{
throw N o t P o s s i b l e E x c e p t i o n ();
}
bool myFunction ()
{
Device d = ge tPower fulDev ice ();
HANDLE h = lockDevice ( d );
bool result = compute ( d );
unlockDevice ( h );
return ( result );
}
62. Was ist RAII? Zur¨ck
u
Kopplung der Belegung und Freigabe von Resourcen an
G¨ltigkeitsbereiche von Variablen
u
Nutzung von Konstruktoren und Destruktoren
Anders als in vielen anderen Sprachen erfolgt der
Destruktoraufruf implizit (¨ber den Stack)
u
C++ verhindert dadurch nicht nur einfaches ”vergessen” von
Freigaben, sondern garantiert Freigaben auch in
Ausnahmesituationen
Java: try {...} finally {...}
C#: using (var) {...}
Common-Lisp: ”Unwind protected macros”
Damit ist in C++ trotzdem kein MemoryManagement wie in
Java oder C# m¨glich
o
new SomeManagedType() kann von MemoryManager kaum
freigegeben, aber durchaus erkannt, werden
C++ erlaubt keine Freigabe von Speicher uber Assemblygrenzen
¨
hinweg
63. Was ist RAII? Zur¨ck
u
L¨sung mit RAII
o
class LockWrapper
{
private :
Handle mHandle ;
public :
LockWrapper ( Device d )
{
mHandle = lockDevice ( h );
}
virtual ~ LockWrapper ()
{
unlockDevice ( mHandle );
}
}
Der Aufruf von unlockDevice() im Destruktor garantiert, dass
unser Ger¨t benutzbar bleibt!
a
64. LEDA Zur¨ck
u
Algorithmus von Kruskal
# include <LEDA/ g r a p h . h>
# include <LEDA/ n o d e p a r t i t i o n . h>
l i s t <edge> MIN SPANNING TREE ( const g r a p h& graph ,
int (∗ cmp ) ( const e d g e &, const e d g e &))
{
l i s t <edge> r e s u l t ; // B e g i n n e m i t dem l e e r e n Wald
// F u e r a l l e Kanten d e s Graphen ( s o r t i e r t )
l i s t <edge> e d g e s = g r a p h . a l l e d g e s ( ) ;
e d g e s . s o r t ( cmp ) ;
// W i e d e r h o l e f u e r a l l e Kanten d e s Graphen
edge c u r r e n t E d g e ;
n o d e p a r t i t i o n p a r t i t i o n ( graph ) ;
f o r a l l ( currentEdge , graph )
{
node u = s o u r c e ( c u r r e n t E d g e ) ;
node v = t a r g e t ( c u r r e n t E d g e ) ;
// U n t e r s u c h e , ob d i e Kante z u g e f u e g t werden kann ,
// s o d a s s d e r Wald w e i t e r h i n k r e i s f r e i b l e i b t
if ( ! p a r t i t i o n . s a m e b l o c k ( u , v ) )
{
r e s u l t . append ( c u r r e n t E d g e ) ;
p a r t i t i o n . union blocks (u , v ) ;
}
}
// Der s o k o n s t r u i e r t e Wald i s t e i n m i n i m a l s p a n n e n d e r
// Baum f u e r den Graphen
return ( r e s u l t ) ;
}
65. Anwendung
Beispiel f¨r einen Netzplan
u
Verschiedene Vorg¨nge
a
mit Abh¨ngigkeiten
a
Jeder Vorgang mit einer
bestimmten Dauer
Aus der Dauer lassen sich
fr¨heste und sp¨teste
u a
Anfangs- und
Endzeitpunkte errechnen
Bau einer Garage
Anwendung als ”Finger¨bung” um ein Gef¨hl f¨r LEDA zu
u u u
bekommen
66. Anwendung
Implementierung eines Netzplans
F¨r Windows und Linux
u
Befehlsorientiertes Dateiformat
Probleme und Fragestellungen
Was ist der ”kritische Pfad”, bei dem eine Verz¨gerung das
o
gesamte Projekt verz¨gern w¨rde?
o u
Ist der Graph Zyklenfrei?
Welche Vorg¨nge h¨ngen von einem bestimmten Vorgang ab?
a a
Was ist eine m¨gliche Reihenfolge in der man den Plan
o
abarbeiten k¨nnte?
o
Errechnung der fr¨hestm¨glichen Anfangszeitpunkte
u o
Fazit: Grunds¨tzliches Vorgehen sehr ¨hnlich!
a a
67. Anwendung
Kritischer Pfad
Ein kritischer Pfad enth¨lt alle Vorg¨nge im Netzplan, deren
a a
Verl¨ngerung das gesamte Projekt gef¨hrden w¨rde
a a u
Gesucht sind also alle l¨ngsten Pfade
a
Weder LEDA noch Boost bieten daf¨r eine fertige L¨sung
u o
Beide Bibliotheken finden jedoch k¨rzeste Wege
u
Ansatz: ”Invertierung” der Vorgangsdauern durch Subtraktion
von konstantem Maximum
Ein k¨rzester Weg in diesem ”invertierten” Graphen ist ein
u
l¨ngster Weg im Ursprungsgraphen
a
Implementierung durch Algorithmus von Dijkstra
68. Anwendung
Zyklenfreiheit
Ein Netzplan bei dem sich ein Zyklus bilden kann k¨nnte per
o
Definition nie erf¨llt werden
u
Wir untersuchen den Graphen also nach dem hinzuf¨gen jeder
u
Kante auf Kreisfreiheit
LEDA bietet daf¨r die Methode graph.Is_Acyclic()
u
Boost bietet daf¨r keine Methode, es wird eine Tiefensuche
u
angewendet
Kreis in einem Netzplan
69. Anwendung
Abh¨ngigkeit von einem bestimmten Vorgang
a
Alle Nachfolger eines bestimmten Knotens
Breiten- oder Tiefensuche, Implementierung mit beiden
Bibliotheken trivial
M¨gliche Abarbeitungsreihenfolge
o
Reihenfolge in der eine einzelne Person die Garage bauen
k¨nnte
o
Topologische Sortierung, Implementierung mit beiden
Bibliotheken trivial
70. Anwendung
Vorw¨rtsrechnung - Definition
a
Fr¨hester Anfangszeitpunkt = FAZ
u
Fr¨hester Endzeitpunkt = FAZ + Dauer = FEZ
u
FAZ (x) = max(pred(x), FEZ )
FAZ (”Begin”) = 0
Vorw¨rtsrechnung - Im Graphen
a
Wegfindungsalgorithmen arbeiten mit Kanten
71. Netzplan Dateiformat
Allgemein
add,<Name>,<Dauer>
→ F¨gt dem Netzplan einen Vorgang hinzu
u
bulkadd,<n>
→ F¨gt dem Netzplan n Vorg¨nge hinzu und f¨gt Kanten von
u a u
Vorg¨ngern zu Nachfolgern hinzu
a
link,<Name>,<Name>
→ Macht den zweiten Eintrag zu einem Nachfolger des Ersten
show,<Name>
→ Zeigt alle Nachfolger des angegebenen Vorgangs
critical
→ Zeigt den kritischen Pfad des Netzplans
order
→ Zeigt eine m¨gliche Reihenfolge, in der die Vorg¨nge
o a
bearbeitet werden k¨nnen
o
clear
→ Leert den Graphen
72. Netzplan Dateiformat
Meta
wait
→ Pausiert die Ausgabe bis der Benutzer ENTER dr¨ckt
u
menu
→ Zeigt das interaktive Men¨, mit dem der Benutzer den
u
Graphen untersuchen und bearbeiten kann
message,<Text>
→ Gibt den Text zur Laufzeit aus
timer,<start|print>,<index>
→ Hilfsmittel f¨r einfache Benchmarks
u