Automatisches Layout von UML

Werbung
Diplomarbeit
Automatisches Layout von
UML-Klassendiagrammen
vorgelegt von
Martin Siebenhaller
Juni 2003
Betreuer: Prof. Dr. M. Kaufmann
Arbeitsbereich Paralleles Rechnen
Wilhelm-Schickard-Institut für Informatik
Fakultät für Informations- und Kognitionswissenschaften
Eberhard-Karls-Universität Tübingen
ii
Inhaltsverzeichnis
1 Einführung
1.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2 Überblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2 Grundlagen
2.1 Graphen . . . . . . . . . . . . . . . . .
2.2 Planarität . . . . . . . . . . . . . . . .
2.3 Orthogonale Zeichnungen von planaren
2.4 Min-Cost-Flow . . . . . . . . . . . . .
. . . . . .
. . . . . .
Graphen
. . . . . .
3 Notation von UML-Klassendiagrammen
3.1 Klassen . . . . . . . . . . . . . . . . . . .
3.2 Beziehungen . . . . . . . . . . . . . . . . .
3.2.1 Vererbung (inheritance) . . . . . .
3.2.2 Assoziation (association) . . . . . .
3.2.3 Abhängigkeit (dependency) . . . .
3.3 Pakete (packages) . . . . . . . . . . . . . .
3.4 Erweiterungsmechanismen . . . . . . . . .
3.4.1 Zusicherungen (constraints) . . . .
3.4.2 Eigenschaften (properties) . . . . .
3.4.3 Stereotypen (stereotypes) . . . . .
3.4.4 Notizen (notes) . . . . . . . . . . .
3.5 Konsequenzen für den Layoutalgorithmus
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
1
4
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5
5
6
9
12
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
15
15
17
17
19
20
20
21
21
22
22
23
24
4 Ästhetikkriterien
25
4.1 Syntaktische Ästhetikkriterien . . . . . . . . . . . . . . . . . 25
4.2 Semantische Ästhetikkriterien . . . . . . . . . . . . . . . . . 28
4.3 Auswahl geeigneter Ästhetikkriterien . . . . . . . . . . . . . 29
5 Der Topology-Shape-Metrics Ansatz
5.1 Definition . . . . . . . . . . . . . . .
5.2 Einbettung . . . . . . . . . . . . . .
5.2.1 GT-Heuristik . . . . . . . . .
5.2.2 Routen von Kanten . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
33
33
35
35
38
iv
INHALTSVERZEICHNIS
5.3
5.4
5.2.3 Rerouting von Kanten .
Orthogonalisierung . . . . . . .
5.3.1 Tamassias Algorithmus .
5.3.2 Das Kandinsky-Modell .
Kompaktierung . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
42
43
43
46
50
6 Ein Layoutalgorithmus für UML-Klassendiagramme
53
6.1 Hyperkanten und Vererbungsgabeln . . . . . . . . . . . . . . . 55
6.2 Der Basisalgorithmus . . . . . . . . . . . . . . . . . . . . . . . 57
6.2.1 Formzuweisung für die aufwärtsgerichteten Kanten . . 57
6.2.2 Knickreduzierung . . . . . . . . . . . . . . . . . . . . . 61
6.2.3 Umsetzung der vorgegebenen Form durch das KandinskyNetzwerk . . . . . . . . . . . . . . . . . . . . . . . . . 64
6.2.4 Einheitliche Ausrichtung der aufwärtsgerichteten Kanten 68
6.3 Verbesserungen des Basisalgorithmus . . . . . . . . . . . . . . 71
6.3.1 Einbettung . . . . . . . . . . . . . . . . . . . . . . . . 71
6.3.2 Höhenkanten . . . . . . . . . . . . . . . . . . . . . . . 77
6.3.3 Behandlung von Selbstschleifen . . . . . . . . . . . . . 81
6.4 Der gesamte Algorithmus . . . . . . . . . . . . . . . . . . . . 84
6.4.1 Überblick . . . . . . . . . . . . . . . . . . . . . . . . . 84
6.4.2 Laufzeit . . . . . . . . . . . . . . . . . . . . . . . . . . 85
7 Implementierung
87
7.1 Design des Layoutalgorithmus . . . . . . . . . . . . . . . . . . 87
7.2 Anwendung des Layoutalgorithmus . . . . . . . . . . . . . . . 90
8 Zusammenfassung und Bewertung
93
A Beispieldiagramme
99
Abbildungsverzeichnis
1.1
Ein kleines UML-Klassendiagramm.
. . . . . . . . . . . . . .
2.1
2.2
2.3
2.4
2.5
Planare Repräsentation eines Graphen. . . . .
Planarer Graph, der nicht Aufwärtsplanar ist.
Orthogonale Gittereinbettung eines Graphen.
Orthogonale Repräsentation eines Graphen. .
Zusammenhang der Zeichenketten. . . . . . .
3.1
3.2
3.3
3.4
Darstellung
Darstellung
Darstellung
Darstellung
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
8
9
10
11
12
einer Klasse in UML-Klassendiagrammen. . . .
von Beziehungen in UML-Klassendiagrammen. .
von Paketen in UML-Klassendiagrammen. . . .
einer Notiz in UML-Klassendiagrammen. . . . .
.
.
.
.
17
18
21
24
4.1
Semantische Ästhetikkriterien. . . . . . . . . . . . . . . . . . .
29
5.1
5.2
5.3
5.4
35
36
40
5.5
5.6
5.7
5.8
5.9
Ersetzung einer Kantenkreuzung durch einen Knoten. . . . .
Darstellung der GT-Heuristik . . . . . . . . . . . . . . . . . .
Darstellung eines st-Graphen und dessen Routinggraph. . . .
Darstellung eines Graphen und dem dazugehörigen dualen
Graph. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Konstruktion des orthogonalen Netzwerks. . . . . . . . . . . .
Beispiel leerer Faces. . . . . . . . . . . . . . . . . . . . . . . .
Verbotene Flüsse im Kandinsky-Modell. . . . . . . . . . . . .
Das Kandinsky-Netzwerk. . . . . . . . . . . . . . . . . . . . .
Ersetzung eines Knotens durch viele kleine Knoten. . . . . . .
42
45
47
48
49
51
6.1
6.2
6.3
6.4
6.5
6.6
6.7
6.8
Ersetzung von Hyperkanten. . . . . . . . . . . . . .
Mögliche Erweiterungen des Hyperkantenkonzepts.
Vom Algorithmus zugewiesene Formen. . . . . . . .
Beispiel zur Knickreduzierung. . . . . . . . . . . .
Unregelmäßige Vereinfachungen . . . . . . . . . . .
Entfernen von Knicken bei Kreuzungsknoten. . . .
Weitere Transformationen bei Kreuzungsknoten. .
Änderungen am Kandinsky-Netzwerks. . . . . . . .
55
57
60
62
62
63
63
65
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
vi
ABBILDUNGSVERZEICHNIS
6.9
6.10
6.11
6.12
6.13
6.14
6.15
Behandlung von ungerichteten Kanten bei der Abbildung auf
das Netzwerk. . . . . . . . . . . . . . . . . . . . . . . . . . . .
Bestimmung der zu richtenden Kanten. . . . . . . . . . . . . .
Zwei Kanten die sich bezüglich der Knotenfolge überschneiden.
Erzeugen von Höhenkanten zwischen Geschwisterknoten. . . .
Verschiedene Fälle, die beim Einfügen von Höhenkanten auftreten. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Zwei alternative Platzierungen einer Selbstschleife. . . . . . .
Aufteilung der Kanten auf die Ports und mögliche Anordnung
der Selbstschleifen. . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
88
89
90
91
8.1
8.2
Schwächen der Einbettung. . . . . . . . . . . . . . . . . . . .
Entstandene Schneckenform. . . . . . . . . . . . . . . . . . . .
95
96
A.1
A.2
A.3
A.4
A.5
A.6
Beispieldiagramm
Beispieldiagramm
Beispieldiagramm
Beispieldiagramm
Beispieldiagramm
Beispieldiagramm
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
82
Grafische Oberfläche des Jar-Inspectors.
UML-Klassendiagramm der verwendeten
Bedienung des Jar-Inspectors. . . . . . .
Nicht ausgerichtete Vererbungsgabeln. .
.
.
.
.
.
.
.
.
.
.
79
81
7.1
7.2
7.3
7.4
1
2
3
4
5
6
. . . . .
Klassen.
. . . . .
. . . . .
67
70
72
77
.
.
.
.
.
.
.
.
.
.
.
.
99
100
101
102
103
104
Tabellenverzeichnis
3.1
3.2
3.3
Vordefinierte Zusicherungen der UML. . . . . . . . . . . . . .
Vordefinierte Eigenschaften der UML. . . . . . . . . . . . . .
Vordefinierte Stereotypen der UML. . . . . . . . . . . . . . .
22
23
23
4.1
Ästhetikpräferenzen für Klassendiagramme. . . . . . . . . . .
30
6.1
Vereinfachung der Form von Kanten . . . . . . . . . . . . . .
61
viii
TABELLENVERZEICHNIS
Kapitel 1
Einführung
1.1
Motivation
In der Softwareentwicklung hat sich seit Anfang der 90er Jahre immer mehr
das objektorientierte Paradigma durchgesetzt. Der Trend zur Objektorientierung wird durch die große Beliebtheit objektorientierter Programmiersprachen wie C++ und Java unterstützt. Bei der objektorientierten Modellierung
werden Objekte der realen Welt wie Personen, Dinge oder Gegenstände auf
Objekte eines Softwaresystems abgebildet. Die Abbildung erfolgt durch geeignete Abstraktion, d.h. es werden nur relevante Eigenschaften der realen
Objekte modelliert. Ein Objekt besitzt einen bestimmten Zustand und ein
bestimmtes Verhalten. Im Objektmodell existiert also keine Trennung zwischen Daten und Funktionalität. Die objektorientierte Softwareentwicklung
zeichnet sich besonders durch hohe Flexibilität, Erweiterbarkeit und Wiederverwendbarkeit aus. Sie erlaubt auch für komplexe Systeme eine sehr natürliche Beschreibung. Ein weiterer Vorteil zu bisherigen Verfahren ist, dass
die Objektorientierung ein durchgängiges Konzept durch die Phasen Analyse, Entwurf und Implementierung bietet und somit den Entwicklungsprozess
vereinfacht und die semantischen Lücken zwischen diesen Phasen schließt.
Zu Beginn der 90er Jahre entstanden viele unterschiedliche Methoden zur
objektorientierten Modellierung mit unterschiedlichen Notationen [19]. Es
fehlte ein einheitlicher Standard. Deswegen entwickelten Booch, Rumbaugh
und Jacobson (die „drei Amigos“) ihre unterschiedlichen Modellierungsansätze zur Unified Modelling Language (UML) weiter. Es handelt sich bei
der UML lediglich um eine grafische Notation, nicht um eine Methode, die
den Entwicklungsprozess der Software vorgibt. Die UML bietet verschiedene
Diagrammtypen mit unterschiedlichem Abstraktionsgrad zur Beschreibung
eines Informationssystems an. Im November 1997 erklärte die Object Management Group (OMG) UML 1.1 zum OMG-Standard für die objektorientierte Modellierung. Durch die hohe Akzeptanz in der Industrie hat sich die
2
KAPITEL 1. EINFÜHRUNG
UML inzwischen als Standardmodellierungssprache für die objektorientierte
Softwareentwicklung etabliert und andere Ansätze nahezu verdrängt.
Klassendiagramme sind ein Diagrammtyp der UML und dienen der Modellierung der statischen Struktur eines Systems [1]. Eine Klasse ist eine Art
Schablone für gleichartige Objekte. Die Objekte einer Klasse werden auch
als deren Instanzen oder Ausprägungen bezeichnet. Die Klasse legt Struktur
und Verhalten der Objekte sowie deren Beziehungen zu anderen Objekten
fest. Eine Klasse wird deshalb auch als abstrakter Datentyp bezeichnet. Klassendiagramme stellen Klassen und deren statische Beziehung untereinander
dar. Oft beinhaltet die Darstellung einer Klasse auch deren Attribut- und
Methodennamen (vgl. Abb. 1.1). In der Softwareentwicklung sind Klassendiagramme der wohl am häufigsten eingesetzte Diagrammtyp.
MidiMessage
− data:byte[]
− length:int
+ <init>
+ setMessage
+ getMessage
+ getStatus
+ getLength
+ clone
MidiEvent
+ message:javax.sound.midi.MidiMessage
+
tick:long
+message
+ <init>
+ getMessage
+ setTick
+ getTick
ShortMessage
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
MIDI_TIME_CODE:int
SONG_POSITION_POINTER:int
SONG_SELECT:int
TUNE_REQUEST:int
END_OF_EXCLUSIVE:int
TIMING_CLOCK:int
START:int
CONTINUE:int
STOP:int
ACTIVE_SENSING:int
SYSTEM_RESET:int
SysexMessage
NOTE_OFF:int
NOTE_ON:int
# SYSTEM_EXCLUSIVE:int
# SPECIAL_SYSTEM_EXCLUSIVE:int
CONTROL_CHANGE:int
PROGRAM_CHANGE:int
+ <init>
+ <init>
+ setMessage
+ setMessage
+ getData
+ clone
POLY_PRESSURE:int
CHANNEL_PRESSURE:int
PITCH_BEND:int
+ <init>
+ <init>
+ setMessage
+ setMessage
+ setMessage
+ getChannel
+ getCommand
+ getData1
+ getData2
+ clone
+ getDataLength
MetaMessage
# META:int
+ defaultMessage:byte[]
+ dataLength:int
+ <init>
+ <init>
+ setMessage
+ getType
+ getData
+ clone
+ writeVarInt
+ <clinit>
Abbildung 1.1: Ein kleines UML-Klassendiagramm.
Die Zahl von Werkzeugen zur Softwareentwicklung, sogenannte CASEWerkzeuge (Computer Aided Software Engineering), steigt ständig. Eine
Hauptaufgabe dieser Werkzeuge ist es, aus Daten automatisch Diagramme zu generieren, um den Entwickler im Entwicklungsprozess zu unterstützen. Ein typisches Beispiel dafür ist die Erzeugung von Klassendiagrammen
aus bereits bestehendem Programmcode, was unter den Begriff ReverseEngineering fällt.
Der Wissenschaftbereich automatisches Graphenzeichnen befasst sich mit
der Entwicklung von Algorithmen zur Informationsvisualisierung. Dabei werden die Elemente von Graphen so geometrisch angeordnet, dass eine mög-
1.1. MOTIVATION
3
lichst „schöne“ und verständliche Zeichnung entsteht. Ein Graph ist ein Konstrukt der diskreten Mathematik, das aus einer Menge von Knoten und einer
Menge von Kanten besteht [4]. Eine Kante verbindet jeweils zwei (nicht notwendigerweise verschiedene) Knoten miteinander. Graphen werden verwendet, um Beziehungen zwischen Objekten zu beschreiben, wobei die Objekte durch Knoten und die Beziehungen durch Kanten repräsentiert werden.
Beim automatischen Graphenzeichnen geht es also darum, Objekte und deren Beziehungen möglichst verständlich darzustellen. Automatisch bedeutet
dabei, dass der Benutzer nicht in den Layoutprozess eingreifen muss. Die
Positionierung der Knoten und Kanten wird allein vom Layoutalgorithmus
bestimmt. Dies ermöglicht eine schnelle und einfache grafische Darstellung
von großen Graphen, die manuell nur mit hohem Aufwand „schön“ dargestellt
werden können.
Die Positionierung der Elemente und somit die Nützlichkeit der Zeichnung wird durch Ästhetikkriterien wie z.B. die Minimierung der Anzahl der
Kantenkreuzungen beeinflusst. Die Wahl der verwendeten Ästhetikkriterien
sowie deren Priorität hängt vom jeweiligen Anwendungsgebiet ab. Da der
Layoutalgorithmus für die Realisierung der Ästhetikkriterien verantwortlich
ist, besitzen unterschiedliche Anwendungsgebiete auch meist unterschiedliche
bzw. modifizierte Layoutalgorithmen. Viele Probleme, die beim automatischen Graphenzeichnen auftreten, wie das Finden eines maximalen planaren
Subgraphen sind NP-vollständig, d.h. die Probleme sind nicht in polynomieller Zeit lösbar. Die Lösung solcher Probleme wird deshalb durch Heuristiken
möglichst gut abgeschätzt.
Durch den steigenden Gebrauch von Diagrammen in Wissenschaft und
Wirtschaft, hat das automatische Zeichnen von Graphen stark an Bedeutung
gewonnen. Diagramme unterstützen die Aussagekraft des zugrundeliegenden
Modelles und erleichtern das Verständnis des dargestellten Sachverhaltes.
Gerade in der Informatik werden sehr häufig Diagramme eingesetzt, z.B.
• Entity-Relationship-Diagramme (ERM) bei der Modellierung eines Datenbanksystems,
• UML-Diagramme bei der Softwareentwicklung,
• Syntaxdiagramme beim Compilerbau
• und Schaltpläne beim Entwurf von VLSI-Schaltungen (Very Large Scale Integration).
Nahezu alle Diagrammtypen lassen sich durch Graphen repräsentieren und
somit auch automatisch zeichnen. Dazu bildet man die Symbole eines Diagrammes auf Knoten und die Verbindungen auf Kanten eines Graphen ab
und entwickelt dann einen geeigneten Layoutalgorithmus. Bei der Entwicklung muss neben der Qualität der Zeichnung auch auf die Laufzeit geachtet
werden, da die Benutzer oft direkt auf die Ausgabe warten. Eine höhere
4
KAPITEL 1. EINFÜHRUNG
Qualität verursacht oft auch eine höhere Laufzeit, es muss also das richtige
Verhältnis zwischen Qualität und Laufzeit gefunden werden.
Ziel dieser Diplomarbeit ist die Entwicklung und Implementierung eines Algorithmus zum automatischen Layout von UML-Klassendiagrammen.
Dazu werden die spezifischen Ästhetikanforderungen von UML-Klassendia–
grammen ermittelt und dann in den Layoutalgorithmus mit einbezogen. Im
Gegensatz zu den meisten bisherigen Ansätzen, die auf einem hierarchischen
Layoutalgorithmus basieren, dient hier ein orthogonaler Layoutalgorithmus
als Basis. Die wesentlichen Modifikationen, die in dieser Diplomarbeit behandelt werden, sind das Aufwärtszeichnen von Kanten und die Verwendung von
Vererbungsgabeln zur Darstellung von Vererbungsbeziehungen. Die Implementierung des Layoutalgorithmus erfolgt in der Programmiersprache Java
unter Verwendung der yfiles-Klassenbibliothek. Als Ausgangspunkt dient das
bestehende Kandinsky-Framework.
1.2
Überblick
Im nächsten Kapitel werden die grundlegenden graphentheoretischen Begriffe erläutert, die in den folgenden Kapiteln vorausgesetzt werden. Kapitel 3
gibt einen Überblick über die UML-Notation und die sich daraus ergebenden Anforderungen an den Layoutalgorithmus. Die Beschreibung verschiedener Ästhetikkriterien sowie die Untersuchung deren Relevanz in Bezug auf
UML-Klassendiagramme erfolgt in Kapitel 4. In Kapitel 5 werden bestehende Algorithmen zum Erzeugen orthogonaler Zeichnungen vorgestellt, die
als Basis für den zu entwickelnden Algorithmus dienen. Die Anpassungen
und Modifikationen, die zum Zeichnen von UML-Klassendiagrammen erforderlich sind, werden in Kapitel 6 beschrieben. Implementierungsspezifische
Designentscheidungen liefert Kapitel 7. Schließlich werden die ermittelten
Ergebnisse im 8. Kapitel nochmals zusammengefasst bevor eine Bewertung
des entwickelten Layoutalgorithmus erfolgt.
Anhang A enthält einige Beispieldiagramme, die mit dem entwickelten
Layoutalgorithmus gezeichnet wurden. Es wurden Beispieldiagramme gewählt, die die Wirkung der einzelnen Modifikationen verdeutlichen.
Kapitel 2
Grundlagen
In diesem Kapitel werden einige grundlegende Begriffe erläutert, die im Laufe
dieser Arbeit verwendet werden.
2.1
Graphen
Die in diesem Abschnitt verwendeten Definitionen stammen im wesentlichen
aus [4] und [7].
Ein Graph G ist ein geordnetes Paar (V, E) zweier Mengen, wobei V die
Menge der Knoten und E die Menge der Kanten ist. Die Kantenmenge E
setzt sich aus gerichteten Kanten ED und ungerichteten Kanten EU zusammen. Es gilt: E = ED ∪ EU . Eine gerichtete Kante e ∈ ED ist ein geordnetes
Paar (v, w) und eine ungerichtete Kante e ∈ EU ist ein ungeordnetes Paar
(v, w), wobei v, w ∈ V . Bei ungerichteten Kanten spielt die Angabe der Reihenfolge der Knoten keine Rolle, d.h. die ungerichtete Kante (v, w) kann auch
durch (w, v) angegeben werden. Die Knoten v und w einer Kante e = (v, w)
werden als Endpunkte der Kante bezeichnet. Sind die beiden Endpunkte
einer Kante identisch, dann nennt man diese Kante eine Selbstschleife (Selfloop). Existieren mehrere Kanten mit denselben Endpunkten, so nennt man
diese Mehrfachkanten. Eine Kante e ist inzident zu einem Knoten v, wenn v
ein Endpunkt der Kante ist. Ein Knoten v ist adjazent zum Knoten w falls
(w, v) ∈ E. Ein Knoten v ist benachbart zum Knoten w falls (v, w) ∈ E oder
(w, v) ∈ E. Ein zu v adjazenter Knoten ist also immer auch ein Nachbar von
v, die Umkehrung gilt nur bei ungerichteten Kanten.
Ein Graph G = (V, E) wird gerichteter Graph genannt, falls gilt E = ED .
Gilt E = EU so nennt man G einen ungerichteten Graph. Ist der Graph G
weder gerichtet noch ungerichtet, so nennt man ihn teilgerichtet. Ein Graph
G0 = (V 0 , E 0 ) ist ein Subgraph von G = (V, E) falls gilt: V 0 ⊆ V und E 0 ⊆ E.
Ist dabei V 0 = V , dann wird G0 als Teilgraph von G bezeichnet. Der Graph
G0 ist der von V 0 ⊆ V induzierte Subgraph von G, falls E 0 alle Kanten aus E
enthält, die Knoten aus V 0 verbinden (v, w ∈ V 0 ∧(v, w) ∈ E ⇒ (v, w) ∈ E 0 ).
6
KAPITEL 2. GRUNDLAGEN
Ein Graph G = (V, E) wird als bipartit bezeichnet, falls die Knotenmenge
V in zwei disjunkte Knotenmengen V1 und V2 aufgeteilt werden kann, so
dass gilt V = V1 ∪ V2 , V1 ∩ V2 = ∅ und für alle Kanten (v, w) ∈ E gilt:
(v ∈ V1 ∧ w ∈ V2 ) oder (v ∈ V2 ∧ w ∈ V1 ).
Der Grad δ(v) eines Knotens v gibt die Anzahl der zu v inzidenten Kanten an. Eine Selbstschleife wird dabei doppelt gezählt. Bei gerichteten Graphen G unterscheidet man zusätzlich zwischen dem Ausgangsgrad δout (v) =
|{w : (v, w) ∈ E}| und dem Eingangsgrad δin (v) = |{w : (w, v) ∈ E}|. Es
gilt dann δ(v) = δin (v) + δout (v). Der Grad eines Knotens v bezüglich der
Kantenmenge E 0 wird mit δE 0 (v) bezeichnet und gibt die Anzahl der zu v
inzidenten Kanten e an, für die gilt e ∈ E 0 . Ein Graph G wird als k-Graph bezeichnet falls gilt: maxv∈V δ(v) ≤ k. Ein Graph G = (V, E) ist zum Graphen
G0 = (V 0 , E 0 ) isomorph, falls eine bijektive Funktion f : V → V 0 existiert, so
dass (u, v) ∈ E ⇔ (f (u), f (v)) ∈ E 0 .
Ein Pfad p von einem Knoten v zu einem Knoten w im Graphen G =
(V, E), besteht aus einer Knotenfolge (v0 , .., vk ), wobei gilt: v0 , .., vk ∈ V ,
v0 = v, vk = w und (vi , vi+1 ) ∈ E für alle i = 0, .., k − 1. Die Länge des
Pfades p ist gleich der Anzahl der abgelaufenen Kanten. Sind die Knoten
v0 , .., vk paarweise verschieden, dann nennt man P einen einfachen Pfad. Ist
v0 = vk dann bildet der Pfad einen Zyklus. Ein Graph G ist azyklisch, falls
kein Knotenpaar (v, w) in G existiert, dass durch einen einfachen zyklischen
Pfad verbunden ist. Ein ungerichteter Graph G ist zusammenhängend, falls
für jedes Knotenpaar v, w ∈ V, v 6= w ein Pfad von v nach w in G existiert.
Ein zusammenhängender, azyklischer und ungerichteter Graph wird auch
als Baum1 bezeichnet. Ein Spannbaum (spanning tree) von G ist ein Baum,
der Teilgraph von G ist und (|V | − 1) Kanten enthält. Ein gewurzelter Baum
(rooted tree) ist ein Baum mit einem ausgezeichneten Knoten r, der als Wurzel des Baumes bezeichnet wird. Sei r die Wurzel eines Baumes T = (V, E)
und v ∈ V ein Knoten. Alle Knoten w ∈ V auf dem Pfad von r nach v werden als Vorgänger von v bezeichnet. Ist w ein Vorgängerknoten von v, dann
ist v ein Nachfolger von w. Der Subbaum von v, ist der Baum, der durch die
Nachfolgerknoten von v induziert wird, wobei v die Wurzel des Baumes ist.
Ist w ein Vorgänger von v und gilt (w, v) ∈ E, dann ist w der Vater von v
und v das Kind von w. Besitzen zwei Knoten den gleichen Vater, dann sind
sie Geschwister. Ein Knoten ohne Kind ist ein Blatt. Jeder Knoten außer der
Wurzel besitzt genau einen Vater.
2.2
Planarität
Eine ebene Einbettung eines Graphen G = (V, E) ist eine Abbildung von G
in den R2 , für die gilt [30]:
1
Der Graph kann auch gerichtete Kanten besitzen, diese werden aber wie ungerichtete
Kanten behandelt.
2.2. PLANARITÄT
7
• Die Knotenmenge V wird auf verschiedene Punkte der Fläche abgebildet.
• Die Kantenmenge E wird auf offene Jordan-Kurven abgebildet, wobei
jede Kurve die zwei Punkte der Fläche verbindet, auf die die Endpunkte
der entsprechenden Kante abgebildet werden.
• Es existiert kein Paar von Kurven, das sich überschneidet.
Ein Graph für den eine ebene Einbettung existiert, kann also überkreuzungsfrei gezeichnet werden.
Definition 1 (Planarität) Ein Graph ist planar, wenn für ihn eine ebene
Einbettung existiert.
Bei der Definition der Planarität spielt es keine Rolle, ob es sich bei dem
Graphen um einen gerichteten oder ungerichteten Graphen handelt. Für jeden planaren Graphen existiert eine kreuzungsfreie Zeichnung. Der Begriff
der Planarität ist allerdings unabhängig von der Zeichnung eines Graphen.
Ein Graph, der in einer Zeichnung Kreuzungen besitzt, kann also trotzdem
planar sein.
Eine ebene Einbettung eines Graphen G = (V, E) teilt die Ebene in verschiedene Regionen auf. Diese Regionen werden Faces genannt. Es existiert
dabei genau ein unbeschränktes Face, dass sogenannte äußere Face. Jede
Kante grenzt zwei, nicht notwendigerweise verschiedene Faces voneinander
ab. Sind die beiden Faces identisch, dann nennt man die Kante eine Brücke.
Ein Face kann niemals von einem anderen Face geschnitten werden, es kann
aber in einem anderen Face enthalten sein.
Die planare Repräsentation P eines eben eingebetteten Graphen G beschreibt dessen Topologie. Für jedes Face f von G besitzt die planare Repräsentation P eine Liste P (f ), die die Kanten enthält, die das Face f begrenzen. Ist f ein inneres Face, dann entspricht die Reihenfolge der Kanten der
zyklischen Reihenfolge, die entsteht, wenn die Kanten von f im Uhrzeigersinn durchlaufen werden. Ist f das äußere Face, entspricht die Reihenfolge
der Kanten der zyklischen Reihenfolge, die entsteht, wenn die Kanten von f
gegen den Uhrzeigersinn durchlaufen werden. Dadurch kann die Repräsentation des äußeren Faces von der des inneren Faces unterschieden werden,
falls beide Faces die gleiche begrenzende Kantenmenge besitzen. Da nicht
festgelegt wird, mit welcher Kante eine Liste P (f ) beginnen muss, ist die
planare Repräsentation nicht eindeutig. Enthält ein Face f eine Brücke e,
so ist e zweimal in der Kantenmenge der Liste P (f ) enthalten (die Kante e
wird dabei in unterschiedliche Richtungen abgelaufen). Jede Kante erscheint
also genau zweimal in den Listen. Es gilt demnach:
X
|P (f )| = 2 · |E|.
(2.1)
f ∈F
8
KAPITEL 2. GRUNDLAGEN
Der Grad eines Faces f wird mit δ(f ) bezeichnet und gibt die Anzahl der
Kanten an, die das Face begrenzen. Es gilt also δ(f ) = |P (f )|.
Damit das äußere Face eindeutig bestimmt ist, wird es in der planaren
Repräsentation entsprechend gekennzeichnet. Die Angabe der Listen P (f ) ist
äquivalent zur Angabe der zyklischen Ordnung der Kanten um die Knoten.
Ein Beispiel für eine planare Repräsentation zeigt Abb. 2.1.
v3
e7
v6
e2
v1
e1
v2
e3
f3
e4
v4
f2
e5
e6
f1 =äußeres Face
P(f1 )=(e2 , e3 , e5 , e6 , e7 )
P(f2 )=(e6 , e5 , e4 , e7 )
P(f3 )=(e1 , e1 , e2 , e4 , e3 )
v5
f1
Abbildung 2.1: Beispiel einer planaren Repräsentation. Die Kante e1 ist eine
Brücke, das Face f1 ist das äußere Face.
Eine wichtige Eigenschaft von planaren Graphen zeigt die Eulersche Formel.
Satz 1 (Eulersche Formel) Sei G = (V, E) ein zusammenhängender, eben
eingebetteter Graph und F die Menge der Faces von G. Dann gilt:
|V | − |E| + |F | = 2.
Ein Beweis zu diesem Satz befindet sich in [20]. Aus der Eulerschen Formel ergibt sich u.a., dass sich die Anzahl der Kanten in einem zusammenhängenden, planaren Graphen linear zur Anzahl der Knoten verhält, denn
unter Nichtberücksichtigung von Selbstschleifen und Mehrfachkanten gilt:
|P (f )| ≥ 3 für alle f ∈ F und wegen Formel 2.1 gilt damit |F | ≥ 32 |E|. Nach
Einsetzen in die eulersche Formel ergibt sich |E| ≤ 3 · |V | − 6. Falls sich die
Anzahl der Mehrfachkanten linear zu der Anzahl der Knoten verhält, gilt also: |E| = O(|V |). Diese Eigenschaft wird häufig für die Laufzeitabschätzung
von Algorithmen auf zusammenhängenden, planaren Graphen verwendet.
Für azyklische, gerichtete Graphen wird der Begriff der Planarität oft
zum Begriff der Aufwärtsplanarität verfeinert.
Definition 2 (Aufwärtsplanarität) Ein gerichteter Graph G ist aufwärtsplanar, wenn er so eben eingebettet werden kann, dass alle Kanten monoton
steigend in eine Richtung zeigen.
Die Richtung der Kanten muss dabei nicht unbedingt aufwärts sein, sie müssen lediglich in dieselbe Richtung zeigen. Die Richtung selbst ist beliebig, da
2.3. ORTHOGONALE ZEICHNUNGEN VON PLANAREN GRAPHEN 9
die Zeichnung entsprechend gedreht werden kann. Aus der Definition ergibt
sich direkt, dass ein aufwärtsplanarer Graph G auch immer planar und azyklisch sein muss. Die Umkehrung gilt nicht (vgl. Abb. 2.2). Ein teilgerichteter
Graph G = (V, ED ∪ EU ) ist aufwärtsplanar, wenn der durch die Kanten ED
induzierte Subgraph von G aufwärtsplanar ist.
6
6
4
5
2
3
1
(a)
4
5
2
3
1
(b)
Abbildung 2.2: Der dargestellte Graph ist zwar planar (a) aber nicht aufwärtsplanar, da die aufwärtsgerichtete Zeichnung (b) eine Kreuzung besitzt.
2.3
Orthogonale Zeichnungen von planaren Graphen
Ein orthogonales Gitter ist eine ebene Einbettung eines unendlichen 4-Graphs,
dessen Knoten ganzzahlige Koordinaten besitzen und dessen Kanten Knotenpaare mit einer Einheitsdistanz verbinden [30]. Eine orthogonale Gittereinbettung eines Graphen G = (V, E) ist eine Abbildung Q von G in das
orthogonale Gitter, für die gilt:
• Jeder Knoten von G wird auf einen unterschiedlichen Punkt des Gitters
abgebildet. Für zwei Knoten v, w ∈ V , v 6= w gilt also: Q(v) 6= Q(w).
• Jede Kante e = (v, w) von G wird auf einen Pfad Q(e) des Gitters
abgebildet, dessen Endpunkte Q(v) und Q(w) sind.
• Die Pfade Q(e1 ) und Q(e2 ) eines beliebigen Kantenpaares e1 , e2 ∈ E
besitzen keine gemeinsamen Punkte, außer gegebenenfalls gemeinsame
Endpunkte.
Ein eben eingebetteter Graph Q(G), der von Q beschrieben wird, ist isomorph zu G. Die horizontalen und vertikalen Abschnitte, aus denen sich
10
KAPITEL 2. GRUNDLAGEN
eine Kante zusammensetzt, werden Segmente der Kante genannt. Alle Winkel einer orthogonalen Gitterzeichnung sind ein Vielfaches von 90 Grad. Ein
Endpunkt eines Segments, auf den kein Knoten abgebildet wird, wird als
Knick bezeichnet. Eine Gittereinbettung Q wird als regionerhaltend bezüglich P bezeichnet, wenn die planare Repräsentation von Q(G) isomorph zu
P ist. Abb. 2.3 zeigt eine orthogonale Gittereinbettung eines vollständigen
Graphen mit vier Knoten.
Abbildung 2.3: Orthogonale Gittereinbettung eines Graphen.
Die Form eines orthogonalen Graphen G wird durch die orthogonale Repräsentation H beschrieben. Diese erweitert die planare Repräsentation um
Informationen über Winkel zwischen Kanten sowie über Kantenknicke. Die
orthogonale Repräsentation H eines planaren 4-Graphen G mit der planaren Repräsentation P enthält für jedes Face f von G eine Liste H(f ). Ein
Listenelement enthält folgende Einträge:
1. eine Kante e von G,
2. eine binäre Zeichenkette s (Bitvektor),
3. und eine Zahl a aus der Menge {90, 180, 270, 360}.
Die Liste H(f ) erhält man, indem man die Liste P (f ) um die Punkte 2) und
3) erweitert. Die Kanten e von H(f ) entsprechen also den Kanten von P (f ).
Die binäre Zeichenkette s beschreibt die Form der Kante e. Eine 0 kodiert
einen Winkel von 90 Grad, eine 1 einen Winkel von 270 Grad. Das k-te Bit
von s gibt den Winkel des k-ten Knickes der Kante e an, auf den man trifft,
wenn man e im Face f im Uhrzeigersinn bzw. gegen den Uhrzeigersinn, falls
f das äußere Face ist, abläuft. Besitzt die Kante e keinen Knick, wird dies
durch ein ε symbolisiert. Die Zahl a gibt den Winkel zwischen der Kante e
und der Kante des in H(f ) folgenden Listenelements an. Abb. 2.4 zeigt ein
Beispiel einer orthogonalen Repräsentation.
Die orthogonale Repräsentation H eines orthogonalen Graphs besitzt die
folgenden Eigenschaften:
2.3. ORTHOGONALE ZEICHNUNGEN VON PLANAREN GRAPHEN11
v3
e2
v2
f3
e4
e7
f2
v6
e6
e1
v1
v4
e3
e5
v5
f1
f1 =äußeres Face
H(f1 )=((e2 , 11, 180), (e3 , , 180), (e5 , , 270), (e6 , , 270), (e7 , , 180))
H(f2 )=((e6 , , 90), (e5 , , 90), (e4 , , 90), (e7 , , 90))
H(f3 )=((e1 , , 360), (e1 , , 90), (e2 , 00, 90), (e4 , , 90), (e3 , , 90))
Abbildung 2.4: Beispiel einer orthogonalen Repräsentation. Die Knicke werden der Kante e2 zugewiesen.
1. Es existiert ein planarer 4-Graph, dessen planare Repräsentation durch
die e-Felder von H(f ) gegeben ist.
2. Seien r1 ∈ H(fi ) und r2 ∈ H(fj ) zwei unterschiedliche Listenelemente
und r1 .e = r2 .e (e trennt die Faces fi und fj ). Dann entspricht die
binäre Zeichenkette r1 .s der binären Zeichenkette die man erhält, wenn
man r2 .s umkehrt und dann negiert (vgl. Abb. 2.5).
3. Für jedes Listenelement r sei
Rotation(r) = Zeros(r.s) − Ones(r.s) + (2 −
r.a
90 ),
wobei Zeros die Anzahl der Nullen und Ones die Anzahl der Einsen in
der binären Zeichenkette s angibt. Da jedes von H beschriebene Face
ein rektilineares Polygon bildet, gilt:
X
Rotation(r) =
r∈H(f )
(
−4 f ist äußeres Face,
+4 sonst.
4. Sei Lv die Menge der Listenelemente r für die v ein Endpunkt der Kante
r.e ist und r.e bezüglich der entsprechenden Liste H(f ) in Richtung
des Knotens v durchlaufen wird. Für jeden Knoten v gilt dann:
X
r∈Lv
r.a = 360
12
KAPITEL 2. GRUNDLAGEN
Die Summe der Winkel von benachbarten Kanten um einen Knoten v
ist also 360 Grad.
Um aus einer orthogonalen Repräsentation eine orthogonale Gittereinbettung zu erhalten, muss noch die Länge der Kantensegmente berechnet werden.
1
0
fi
1
1
0
fj
e
2
0
1
Abbildung 2.5: Zusammenhang der Zeichenketten. Durchläuft man die Kante
e im Face fj , so entsteht die Zeichenkette „110“. Durchläuft man e im Face
fi , so entsteht die Zeichenkette „100“.
Mit der orthogonalen Repräsentation lassen sich bis jetzt nur 4-Graphen
beschreiben. Ein Knoten v mit δ(v) > 4, besitzt in einer orthogonalen Zeichnung mindestens eine Seite an der sich mehrere Kanten befinden. Der von
diesen Kanten eingeschlossene Winkel ist somit ein 0 Grad Winkel. Um 0
Grad Winkel in die orthogonale Repräsentation mit aufzunehmen, erlaubt
man für die Zahl a, die den Winkel angibt, auch einen Wert von 0. Eine orthogonale Repräsentation, die 0 Grad Winkel zulässt, wird quasi-orthogonale
Repräsentation genannt.
2.4
Min-Cost-Flow
Das Finden einer knickminimalen orthogonalen Repräsentation erfolgt durch
das Lösen eines Min-Cost-Flow-Problems, welches ein Netzwerkflussproblem
darstellt.
Ein Netzwerk N = (V, E) ist ein gerichteter Graph mit zwei ausgezeichneten Knoten, einer Quelle s und einer Senke t, wobei gilt: δin (s) = 0 und
δout (t) = 0. Auf der Menge der Kanten wird eine nichtnegative Funktion
cap : E → R≥0 definiert, welche die Kapazität der Kanten angibt. Für alle
Knoten v, w ∈ V ∧ (v, w) ∈
/ E gilt: cap(v, w) = 0.
Ein Fluss im Netzwerk N ist eine Funktion f : V × V → R, die folgende
Eigenschaften besitzt:
(1)
f (v, w) = −f (w, v)
für alle Knoten v, w ∈ V ,
(2)
f (v, w) ≤ cap(v, w)
für alle Knoten v, w ∈ V ,
2.4. MIN-COST-FLOW
(3)
X
13
für alle Knoten v ∈ V \ {s, t}.
f (v, w) = 0
w∈V
Eigenschaft (1) wird als Schiefsymmetrie bezeichnet. Durch die Kapazitätsbedingung (2) wird der Fluss, der über eine Kante fließen kann, durch deren
Kapazität beschränkt. Die Flusserhaltungsbedingung (3) sagt aus, dass für
jeden Knoten v ∈ V \ {s, t} der gesamte Fluss in den Knoten hinein gleich
dem gesamten Fluss aus dem Knoten heraus ist. Der Wert |f | eines Flusses
f entspricht dem Fluss aus dem Quellknoten heraus. Es gilt also:
X
|f | =
f (s, v).
v∈V
Ein Fluss f ist maximal, wenn sein Wert |f | mindestens so groß ist, wie der
Wert jedes anderen Flusses.
Bei einem Min-Cost-Flow-Problem wird zusätzlich eine Kostenfunktion
cost : E → R auf den Kanten des Netzwerkes N definiert, welche die Kosten
angibt, die beim Transport einer Flusseinheit über die Kante anfallen.
Die Kosten eines Flusses f sind wie folgt definiert:
X
cost(f ) =
f (e) · cost(e).
e∈E
Ein Min-Cost-Flow ist ein maximaler Fluss minimaler Kosten.
14
KAPITEL 2. GRUNDLAGEN
Kapitel 3
Notation von
UML-Klassendiagrammen
Dieses Kapitel bietet einen Überblick über die wichtigsten Notationselemente
von UML-Klassendiagrammen und basiert im wesentlichen auf [19] und [24].
Es existieren Elemente für Klassen, verschiedene Beziehungen und Pakete.
Für die genauere Spezifizierung von Elementen besitzt die UML außerdem
verschiedene eingebaute Erweiterungsmechanismen, wie Zusicherungen, Eigenschaften, Stereotypen und Notizen. Bei den genannten Erweiterungen
handelt es sich, bis auf die Notiz, nicht um neue Elemente, sondern lediglich
um eine geeignete Beschriftung der Grundelemente. Im folgenden werden zuerst die Grundelemente und dann die Erweiterungsmechanismen vorgestellt.
3.1
Klassen
Eine Klasse wird durch ein Rechteck mit drei, jeweils durch horizontale Linien getrennte, Komponenten dargestellt.
Die oberste Komponente enthält den Klassennamen in zentrierter, fetter
Schrift. Handelt es sich um eine abstrakte Klasse, wird er zusätzlich kursiv
geschrieben. Der Name beginnt mit einem Großbuchstaben. Die Komponente kann außerdem auch eine Erweiterung für die genauere Spezifizierung der
Klasse enthalten. Stereotypen werden zentriert über dem Klassennamen angegeben. Die Angabe von Eigenschaften erfolgt unter dem Klassennamen.
Die genauere Spezifizierung der Erweiterungen folgt in Abschnitt 3.4.
Die mittlere Komponente enthält die Attribute einer Klasse. Ein Attribut
wird durch folgende Syntax spezifiziert:
Sichtbarkeit Name: Typ = Defaultwert {Eigenschaften} .
Für die Sichtbarkeit (visibility) eines Elements kennt die UML folgende Werte:
16
KAPITEL 3. NOTATION VON UML-KLASSENDIAGRAMMEN
• „+“ für öffentliche (public) Sichtbarkeit. Ein solches Element ist für
alle Klassen sichtbar.
• „#“ für geschützte (protected) Sichtbarkeit. Ein solches Element ist nur
innerhalb der definierenden Klasse und in deren Unterklassen sichtbar.
• „-“ für private (private) Sichtbarkeit. Ein solches Element ist nur innerhalb der definierenden Klasse sichtbar.
Eine fehlende Sichtbarkeitsangabe bedeutet lediglich, dass die Angabe unterdrückt wird, nicht das die Sichtbarkeit nicht definiert ist. Der Name eines
Attributs wird üblicherweise klein geschrieben. Für die Angabe des Typs
wird meistens die entsprechende Typbezeichnung der verwendeten Programmiersprache benutzt. Besitzt ein Attribut keinen Defaultwert, so folgt die
Angabe der Eigenschaften direkt nach der Angabe des Typs. Als Eigenschaften können dabei auch Zusicherungen angegeben werden. Werden Stereotypen angegeben, stehen diese vor der Sichtbarkeitsangabe. Es besteht auch
die Möglichkeit, Stereotypen oder Eigenschaften über einem Attributelement
anzugegeben. Sie gelten dann für sämtliche Elemente bis zur nächsten Angabe.
Die unterste Komponente enthält die Methoden der Klasse. Methoden1 ,
die lediglich zum setzen und lesen von Attributwerten dienen, werden häufig
weggelassen. Die Syntax für die Darstellung einer Methode lautet:
Sichtbarkeit Name (Parameter) : Rückgabetyp {Eigenschaften} .
Für die Angabe der Sichtbarkeit, der Eigenschaften und der Stereotypen gilt
dasselbe wie bei den Attributen. Der Name einer Methode entspricht meist
dem Methodennamen in der Implementierung. Die Angabe der Parameter
und des Rückgabetyps ist optional. Werden Parameter angegeben, besitzen
sie folgende Syntax:
Art Name: Implementierungstyp = Defaultwert .
Für die Art eines Parameters sind folgende Werte zulässig:
• „in“ für Eingabeparameter,
• „out“ für Ausgabeparameter,
• „inout“ falls beides zutrifft.
Für den Implementierungstyp und den Defaultwert gilt dasselbe wie bei
den Attributen. Werden mehrere Parameter angeben, so werden diese durch
Komma getrennt. Eine abstrakte Methode kann durch die Eigenschaft „{abstract}“ oder durch Kursivschrift der Signatur gekennzeichnet werden.
1
Die Begriffe Methode und Operation werden hier nicht unterschieden.
3.2. BEZIEHUNGEN
17
Der Gültigkeitsbereich (scope) gibt an, ob ein Attribut oder eine Methode statisch (static members) ist. Ein statisches Attribut (Klassenattribut)
existiert nur einmal und unabhängig von den Instanzen der Klasse. Eine
statische Methode (Klassenmethode) operiert auf der Klasse und nicht auf
einem Objekt. Klassenattribute und -methoden werden unterstrichen dargestellt.
Wenn die Angabe der Attribute oder Methoden nicht erforderlich ist, können die entsprechenden Komponenten weggelassen werden. Außerdem können benutzerdefinierte Komponenten angefügt werden, wie z.B. eine Komponente für die Angabe von Ausnahmen (exceptions). In Abbildung 3.1 werden
verschiedene Darstellungen von Klassen gezeigt.
Klasse A
+nummer: int = 0
-flag: boolean = false
+setzeFlag(in flag:boolean)
#berechneWert(): int
#berechneWert(): int
(a)
(b)
Subklasse
«interface»
Schnittstelle
(c)
Abbildung 3.1: Darstellung einer Klasse in UML-Klassendiagrammen.
3.2
Beziehungen
Klassendiagramme können verschiedene statische Beziehungsarten darstellen. Dazu gehören Vererbung, Assoziation und Abhängigkeit.
3.2.1
Vererbung (inheritance)
Die Vererbung beschreibt Generalisierungs- und Spezialisierungsbeziehungen, d.h. Beziehungen zwischen einer allgemeineren und einer spezifischeren
Klasse. Die allgemeinere Klasse wird als Superklasse (Oberklasse) und die
spezifischere als Subklasse (Unterklasse) bezeichnet. Eine Subklasse erbt alle
Eigenschaften (Attribute und Methoden) ihrer Superklasse und kann darüber
hinaus noch weitere Eigenschaften definieren. Eine Instanz der Subklasse
kann somit auch als Instanz der Superklasse verwendet werden (Polymorphismus). Die Subklasse zeigt geerbte Eigenschaften im Klassendiagramm
18
KAPITEL 3. NOTATION VON UML-KLASSENDIAGRAMMEN
nur nochmals an, falls sie diese geändert hat, z.B. beim Überschreiben einer
Methode (vgl. Abb. 3.1(b)). Die Vererbungsbeziehung wird durch eine Linie
zwischen der Subklasse und der Superklasse repräsentiert, wobei das Linienende an der Superklasse mit einem transparenten Dreieck versehen wird,
dessen Spitze auf die Superklasse zeigt. Dieselbe Darstellung wird auch für
die Schnittstellenvererbung verwendet, d.h. wenn sowohl die Sub- als auch
die Superklasse eine Schnittstelle ist. Wird eine Schnittstelle von einer Klasse
implementiert, d.h. die Superklasse ist eine Schnittstelle und die Subklasse
eine gewöhnliche Klasse, dann wird die Vererbungslinie gestrichelt gezeichnet
(vgl. Abb. 3.2(b)). Besitzt eine Superklasse mehrere Subklassen, dann können die Vererbungslinien auch als Vererbungsgabel dargestellt werden (vgl.
Abb. 3.2(a)). Eine Vererbungslinie kann außerdem durch einen Diskriminator
beschriftet werden. Dieser gibt das Unterscheidungsmerkmal der Subklassen
an, das für die Bildung der Vererbungshierarchie ausschlaggebend war. Die
Subklassen einer Superklasse können auch unterschiedliche Diskriminatoren
besitzen. Beim Verwenden von Vererbungsgabeln werden Stereotypen und
Eigenschaften am Linienende der Superklasse platziert. Ansonsten werden
sie an einer gestrichelten Linie platziert, die alle beteiligten Vererbungslinien
kreuzt.
Superklasse
«interface»
Schnittstelle
Subklasse 1
Subklasse 2
Subklasse 3
Klasse 1
(a)
Klasse 1
Rolle 1
1
Assoziation
Rolle 2
0..1,4
Klasse 2
(c)
Klasse 2
(b)
Klasse 1
Ganzes
2
Aggregation
Teil
0..5
Klasse 2
(d)
Klasse 1
Klasse 1
Ganzes
1
Komposition
Abhängigkeit
Teil
0..5
Klasse 2
Klasse 2
(e)
(f)
Abbildung 3.2: Darstellung von Beziehungen in UML-Klassendiagrammen.
3.2. BEZIEHUNGEN
3.2.2
19
Assoziation (association)
Eine Assoziation beschreibt die Beziehung zwischen Instanzen (Objekte) von
Klassen. Sie wird durch eine Linie dargestellt, die die beteiligten Klassen
verbindet (vgl. Abb. 3.2(c)). Eine Assoziation drückt eine Bekanntschaft der
beteiligten Objekte aus. Meistens kennen sich die Objekte gegenseitig, man
spricht dann von einer bidirektionalen Assoziation. Bei einer unidirektionalen
Assoziation gilt die Bekanntschaft nur in eine Richtung. Die Assoziationslinie
wird dann mit einer Pfeilspitze versehen, so das der Pfeil vom „wissenden“
zum „unwissenden“ Objekt zeigt. Man spricht dabei auch von Navigierbarkeit (navigability) in eine bzw. in beide Richtungen. Die Assoziationslinie kann außerdem mit einem Assoziationsnamen beschriftet werden. Um
die Leserichtung der Assoziation zu bestimmen, kann beim Assoziationsname ein Pfeil in Form eines gefüllten Dreiecks angebracht werden. Bei einer
binären Assoziation sind genau zwei Klassen an einer Beziehung beteiligt.
Steht eine Klasse zu sich selbst in Beziehung, handelt es sich um eine reflexive Assoziation. Die verschiedenen Instanzen der Klasse, die an der reflexiven Assoziation beteiligt sind, nehmen dabei unterschiedliche Rollen ein.
Eine Rolle gibt die Bedeutung einer Klasse innerhalb der Assoziation an.
Der Rollenname steht an dem Ende der Assoziationslinie, an dem sich die
beschriebene Klasse befindet. Vor dem Rollenname kann eine Sichtbarkeitsangabe wie bei Attributen und Methoden stehen. Auf die explizite Angabe
einer Rolle kann verzichtet werden, falls diese aus dem Klassennamen abgeleitet werden kann. Existieren mehrere Assoziationsbeziehungen zwischen
zwei Klassen oder handelt es sich um eine reflexive Assoziation, so muss
die Rolle stets explizit angegeben werden. Assoziationslinien, Rollennamen
und Assoziationsnamen können außerdem durch Zusicherungen, Eigenschaften oder Stereotypen genauer spezifiziert werden. Die Angabe erfolgt jeweils
in der Nähe der entsprechenden Komponente.
Die Kardinalität (multiplicity) gibt an, wieviele Objekte einer Klasse A
an einer Beziehung zu einem Objekt der Klasse B beteiligt sind. Die Kardinalität steht dabei an dem Ende der Assoziationslinie, an der sich die Klasse
A befindet. Sie wird dabei in folgendem Format angegeben:
untere-Schranke .. obere-Schranke .
Die untere Schranke gibt die minimale Anzahl und die obere Schranke die
maximale Anzahl, der an der Beziehung beteiligten Objekte an. Wird nur
ein einzelner Wert angegeben, bedeutet dies, dass die untere Schranke gleich
der oberen Schranke ist. Es sind auch durch Komma getrennte Kombinationen dieser Angaben möglich (z.B. 1..3,5,7..∗). Ein Stern „∗“ gibt an, dass
beliebig viele Objekte an einer Beziehung teilnehmen können. Bei einer unteren Schranke von 0 existiert eventuell gar keine Beziehung zu einem anderen
Objekt.
20
KAPITEL 3. NOTATION VON UML-KLASSENDIAGRAMMEN
Eine Assoziation kann selbst Attribute und Methoden sowie Assoziationen zu anderen Klassen besitzen. Dies kann durch eine Assoziationsklasse
modelliert werden. Die Darstellung einer Assoziationsklasse unterscheidet
sich nicht von der Darstellung einer gewöhnlichen Klasse. Die Assoziationsklasse wird aber durch eine gestrichelte Linie mit der Assoziationslinie
verbunden.
Es existieren zwei Spezialfälle von Assoziationsbeziehungen, die Aggregation und die Komposition. Die Aggregation beschreibt eine Beziehung,
bei der ein Objekt A Teil eines anderen Objekts B ist. Die Klasse des Objekts A wird bezüglich der Aggregation als Teilklasse bezeichnet, die Klasse
des Objekts B als Aggregatsklasse. Die Unterscheidung zwischen Assoziation und Aggregation ist nicht immer einfach. Man spricht aber grundsätzlich
nur dann von Aggregation, wenn das Teil ein fester Bestandteil des Ganzen
ist. Die Aggregation wird durch einen transparenten Diamanten am Ende der
Assoziationslinie der Aggregatsklasse dargestellt (vgl. Abb. 3.2(d)). Bei einer
Komposition wird der Diamant gefüllt gezeichnet (vgl. Abb. 3.2(e)). Die
Komposition stellt einen Sonderfall der Aggregation dar mit den folgenden
Eigenschaften:
• Ein Teil existiert nur höchstens so lange wie das Ganze. Beim Löschen
des Ganzen werden auch die Teile gelöscht.
• Die Kardinalität der Aggregatsklasse darf nicht größer als eins sein
(strong ownership).
3.2.3
Abhängigkeit (dependency )
Eine Abhängigkeit ist ein Beziehung zwischen zwei Elementen, bei der die
Änderung des einen Elements möglicherweise auch eine Änderung des anderen Elements (abhängiges Element) erforderlich macht. Bei einer Abhängigkeit stehen die Elemente selbst in Beziehung zueinander, unabhängig von
den Instanzen. Abhängigkeiten werden durch einen gestrichelten Pfeil dargestellt, wobei sich das abhängige Element am Fuß des Pfeils befindet (vgl.
Abb. 3.2(f)). Der Pfeil kann durch einen Namen oder einen Stereotyp beschriftet werden. Abhängigkeiten, die durch andere Beziehungsarten impliziert werden, werden normalerweise nicht nochmals gesondert dargestellt.
3.3
Pakete (packages)
Pakete dienen der Gruppierung von Elementen. Ein Paket ist eine Art benannter Behälter für Elemente und kann auch weitere Pakete enthalten. Bei
einer geeigneten Gruppierung sorgen Pakete für ein übersichtliches System.
Pakete werden durch ein Rechteck mit Reiter dargestellt (wie ein Aktenordner). Wird der Inhalt des Pakets angezeigt, steht der Paketname im Reiter, ansonsten wird er innerhalb des Rechtecks platziert (vgl. Abb. 3.3).
3.4. ERWEITERUNGSMECHANISMEN
21
Stereotypen werden über den Paketnamen und Eigenschaften oder ZusichePaket 2
Paket 1
Klasse 1
Klasse 2
Abbildung 3.3: Darstellung von Paketen in UML-Klassendiagrammen.
rungen hinter oder unter dem Paketnamen angegeben. Ein Paket definiert
einen Namensraum. Die in einem Paket enthaltenen Klassen- und Paketnamen müssen eindeutig sein, es können aber Klassen oder Pakete mit gleichem
Namen in verschiedenen Paketen existieren. Eine Referenz zu einer Klasse
in einem anderen Paket wird durch
Paketname::Klassenname
angegeben. Da Pakete ineinander verschachtelt sein können, kann der Pfad
zu einer Klasse aus mehreren durch „::“ getrennten Paketnamen bestehen.
Der qualifizierte Name einer Klasse, der aus Paketpfad und Klassenname
besteht, ist also immer eindeutig. Beziehungen zwischen Paketen werden
durch Abhängigkeiten modelliert.
3.4
Erweiterungsmechanismen
Die Anzahl verschiedener Notationselemente in Klassendiagrammen ist recht
gering. Um dennoch möglichst viel Semantik in den Diagrammen unterbringen zu können, bietet die UML Erweiterungen für die Angabe von Zusicherungen, Eigenschaften, Stereotypen und Notizen an. Da es sich dabei, bis auf
die Notiz, lediglich um eine geeignete Beschriftung der Grundelemente handelt, wird die Anzahl der verschiedenen Elemente weiterhin überschaubar
gehalten.
3.4.1
Zusicherungen (constraints)
Durch Zusicherungen kann man Einschränkungen und Invarianten für Elemente formulieren. Zusicherungen sind Ausdrücke, die stets wahr sein müssen. In der UML kann eine Zusicherung frei formuliert werden, sie muss dabei
lediglich von geschweiften Klammern umschlossen sein. Falls z.B. ein Kunde einer Firma ein Mindestalter von 18 haben muss, kann dies durch die
22
KAPITEL 3. NOTATION VON UML-KLASSENDIAGRAMMEN
Zusicherung {Alter >= 18} ausgedrückt werden. Die Formulierung kann sowohl in Umgangssprache als auch durch einen Ausdruck einer Programmiersprache erfolgen. Inzwischen existieren auch spezielle Sprachen für die Formulierung von Zusicherungen, wie die Object Constraint Language (OCL).
Neben den benutzerdefinierten Zusicherungen existieren auch bereits vordefinierte Zusicherungen in der UML. Einige davon werden in Tabelle 3.1
erläutert. Gilt eine Zusicherung für mehrere Elemente, kann sie sich auch in
einer Notiz (s. Notizen auf S.23) befinden und durch gestrichelte Linien mit
den entsprechenden Elementen verbunden werden.
Zusicherung Element
{complete}
Vererbung
Bedeutung
Alle Subklassen wurden spezifiziert,
es können keine weiteren hinzukommen.
{ordered}
Assoziation
Menge der Objekte auf der Zielseite
der Assoziation sind geordnet.
{xor}
Assoziation
Objekt kann nur an einer der angegebenen Assoziationen beteiligt
sein.
Tabelle 3.1: Vordefinierte Zusicherungen der UML.
3.4.2
Eigenschaften (properties)
Für die Angabe von Eigenschaften eines Elements, für die keine graphische
Notation existiert, können benutzerdefinierte Eigenschaften verwendet werden. Diese werden als Schlüsselwort-Wert-Paare (tagged value) angegeben
und wie Zusicherungen von geschweiften Klammern umschlossen. In einem
Klammerpaar können mehrere durch Komma getrennte Eigenschaften stehen. Eine Eigenschaft besitzt folgende Syntax:
Schlüsselwort = Wert .
Das Schlüsselwort gibt den Namen der Eigenschaft an, der innerhalb des
betreffenden Elementtyps eindeutig sein muss. Besitzt die Eigenschaft einen
boolschen Typ, so ist ihr Defaultwert true, d.h. die Angabe des Wertes kann
entfallen. Trifft eine Eigenschaft nicht zu (Wert = false) wird sie einfach
nicht angegeben. Einige von der UML vordefinierte Eigenschaften werden in
Tabelle 3.2 aufgezählt.
3.4.3
Stereotypen (stereotypes)
Stereotypen ermöglichen die genauere Klassifizierung von Elementen. Ein
Klassenelement repräsentiert z.B. sowohl eine normale Klasse wie auch eine
3.4. ERWEITERUNGSMECHANISMEN
Eigenschaft
{abstract}
23
Element
Methode, Klasse
Bedeutung
Alternative Darstellung von abstrakten Klassen bzw. Methoden
(anstatt kursivem Namen)
{frozen}
Attribut
Ein einmal definierter Wert kann
nicht mehr geändert werden
{query}
Methode
Methode hat keine Seiteneffekte
(Systemzustand bleibt erhalten)
Tabelle 3.2: Vordefinierte Eigenschaften der UML.
Schnittstelle. Durch die Angabe eines Stereotyps kann nun ein entsprechender Untertyp des Elements gebildet werden (vgl. Abb. 3.1(c)). Im Unterschied zu Eigenschaften, erweitern Stereotypen das Metamodell und somit
die Modellierungssprache. Tabelle 3.3 zeigt einige von der UML vordefinierte Stereotypen und deren Bedeutung. Der Name eines Stereotyps wird stets
von französischen Anführungszeichen («, ») umschlossen. Neben vordefinierten Stereotypen können auch benutzerdefinierte eingeführt werden.
Stereotyp
«access»
Bedeutung
Quellpaket darf öffentliche Elemente
des Zielpaketes referenzieren
«constructor» Methode
Methode ist ein Konstruktor
«extends»
Vererbung
Vererbung um erweiterte Funktionalität anzubieten
«interface»
Klasse
Klasse ist eine Schnittstelle
«utility»
Klasse
Klasse besitzt nur statische Methoden und Attribute
Tabelle 3.3: Vordefinierte Stereotypen der UML.
3.4.4
Element
Abhängigkeit
Notizen (notes)
Wichtige Informationen über Elemente, die mit den bisher vorgestellten Erweiterungsmechanismen nicht dargestellt werden können, können durch Notizen in das Klassendiagramm aufgenommen werden. Eine Notiz dient jedoch
nicht der Erweiterung der Semantik, sie wird lediglich zur genaueren Erläuterung eines Sachverhalts oder einer Entscheidung verwendet. Eine Notiz
wird durch ein Rechteck mit einem Eselsohr in der rechten oberen Ecke dargestellt und kann beliebigen Text enthalten (vgl. Abb. 3.4). Sie kann durch
eine gestrichelte Linie mit den betreffenden Elementen verbunden werden.
24
KAPITEL 3. NOTATION VON UML-KLASSENDIAGRAMMEN
Notiz für
Klasse 1 und
Klasse 2
Klasse 1
Notiz zur
Assoziation
Klasse 2
Abbildung 3.4: Darstellung einer Notiz in UML-Klassendiagrammen.
Es existieren noch weitere Erweiterungen und Elemente wie z.B. parametrisierte Klassen (templates), abgeleitete Assoziationen, abgeleitete Attribute
und n-fach Assoziationen. Da die meisten Klassendiagramme aber ohne diese
Elemente auskommen, werden sie hier nicht erläutert. Die genaue Spezifikation aller Elemente und Erweiterungen befindet sich in [24].
3.5
Konsequenzen für den Layoutalgorithmus
In den vergangenen Abschnitten wurden die verschiedenen Elemente von
UML-Klassendiagrammen vorgestellt. Da der Layoutalgorithmus einen Graphen als Eingabe erwartet, müssen die Elemente entsprechend auf diesen
abgebildet werden. Klassen und Pakete werden dabei auf die Knoten und
Beziehungen auf die Kanten des Graphen abgebildet. Für den Eingabegraph
gilt außerdem folgendes:
• Da eine Klasse zu sich selber in Beziehung stehen kann, enthält der
Eingabegraph möglicherweise Selbstschleifen.
• Da verschiedene Beziehungen zwischen zwei Klassen existieren können,
enthält der Eingabegraph möglicherweise Mehrfachkanten.
• Die Größe der Knoten hängt von der Anzahl und der Länge der Attributund Methodensignaturen ab und ist somit variabel. Der Eingabegraph
enthält also Knoten unterschiedlicher Größe.
• UML-Klassendiagramme lassen sich auf allgemeine, teilgerichtete Graphen abbilden.
• Die Elemente von UML-Klassendiagrammen können zusätzliche Beschriftungen enthalten, wie z.B. Rollennamen, Kardinalitäten und Stereotypen. Diese müssen an den Eingabegraphen übermittelt und dann
vom Layoutalgorithmus geeignet platziert werden.
Kapitel 4
Ästhetikkriterien
Ein Layoutalgorithmus soll möglichst ansprechende Zeichnungen erzeugen.
Um dies zu erreichen müssen zunächst einmal die ästhetischen Anforderungen ermittelt werden, die an die entstehenden Zeichnungen gestellt werden.
Da die Graphen, je nach Anwendungsbereich, eine unterschiedliche Bedeutung besitzen, variieren die Anforderungen entsprechend. Ästhetikkriterien
legen Grundsätze fest, die für eine möglichst übersichtliche und verständliche
Darstellung der durch den Graphen repräsentierten Elemente und Beziehungen sorgen sollen.
Bei Klassendiagrammen werden, wie bereits erwähnt, Klassen- und Packetelemente auf Knoten und Beziehungen auf Kanten abgebildet. Die UML gibt
die Bedeutung und Notation der Elemente vor, aber nicht wie diese im Diagramm möglichst lesbar dargestellt werden. Die ermittelten Ästhetikkriterien
müssen vom Layoutalgorithmus durch eine entsprechende grafische Anordnung der Elemente realisiert werden. Damit ein Layoutalgorithmus in der
Praxis sinnvoll eingesetzt werden kann, müssen die gewählten Ästhetikkriterien von Algorithmen in polynomieller Zeit umgesetzt werden können.
In den folgenden beiden Abschnitten werden verschiedene syntaktische
und semantische Ästhetikkriterien vorgestellt. Anschließend wird deren Relevanz und Bedeutung bezüglich Klassendiagrammen untersucht, um eine
geeignete Menge zu finden, die vom Layoutalgorithmus berücksichtigt werden soll.
4.1
Syntaktische Ästhetikkriterien
Bereits aus der abstrakten Graphstruktur lassen sich Ästhetikkriterien ableiten. Diese werden als syntaktische Ästhetikkriterien bezeichnet, da sie keinen
Bezug auf die Semantik der einzelnen Elemente nehmen. Sie legen einfache,
grafische Grundsätze fest, die allgemein für Zeichnungen von Graphen zutreffen und somit meistens sinnvoll eingesetzt werden können. Es folgt eine
Auswahl der verbreitetsten syntaktischen Ästhetikkriterien [6, 32]:
26
KAPITEL 4. ÄSTHETIKKRITERIEN
Abstand zwischen Knoten
Um eine lesbare Zeichnung zu bekommen, sollten sich die Knoten nicht
überlappen und nicht zu nahe aneinander platziert werden. Der geeignete Abstand hängt von der Knotengröße und der Anzahl der Kanten
an den Knoten ab. Werden Knoten zu weit weg voneinander platziert,
führt dies zu einem höherem Flächenverbrauch sowie zu längeren Kanten zwischen den Knoten.
Länge der Kanten
Zeichnungen mit kurzen Kanten sind in der Regel einfacher zu lesen, da
sich die verbundenen Knoten nahe aneinander befinden. Lange Kanten
besitzen oft mehrere Kreuzungen und Knicke. Sind Kanten zu kurz, ist
der Abstand zwischen zwei Knoten zu gering.
Es kann auch auf eine möglichst einheitliche Kantenlänge geachtet werden. Dieses Kriterium ist aber schwer zu realisieren und steht im Konflikt mit einigen anderen, noch folgenden Kriterien.
Abstand zwischen Knoten und Kanten
Kanten, die an einem Knoten vorbeigehen, sollten nicht zu dicht an diesem platziert werden, damit die Zeichnung übersichtlich bleibt. Kanten
sollten sich außerdem nicht überlappen. Zwei parallele Kantensegmente
sollten einen Mindestabstand einhalten, damit sie besser unterschieden
werden können.
Anzahl der Kantenkreuzungen
Kreuzungen zwischen Kanten machen den Verlauf einer Kante unübersichtlich. Bei vielen Kreuzungen wird eine Zeichnung daher schnell unleserlich. Es gilt deshalb, die Anzahl der Kreuzungen möglichst klein
zu halten. Ganz vermeiden lassen sich Überkreuzungen nur bei planaren Graphen. UML-Klassendiagramme sind aber i.a. keine planaren
Graphen.
Anzahl der Kantenknicke
Kantenknicke werden von Algorithmen produziert, die die Kanten nicht
geradlinig oder als Kurven zeichnen. Durch viele Kantenknicke wird eine Zeichnung schwerer lesbar, da dem Kantenverlauf schwerer zu folgen
ist. Neben der Minimierung der Gesamtzahl kann auch auf die Ausgewogenheit von Knicken geachtet werden, d.h. jede Kante soll z.B.
höchstens k Knicke besitzen.
Verteilung der Knoten über die Zeichenfläche
Eine gleichmäßige Verteilung der Knoten über die Zeichenfläche führt
zu einer übersichtlichen Zeichnung bezüglich der Knoten. Allerdings
steht dieses Kriterium in Konflikt zu vielen anderen Kriterien. Eine
4.1. SYNTAKTISCHE ÄSTHETIKKRITERIEN
27
gleichmäßige Verteilung kann z.B. zu langen Kanten und vielen Kantenknicken führen. Gerade wenn Graphelemente eine spezielle Semantik haben, ist dieses Kriterium eher unpraktikabel.
Platzierung von Väterknoten
Häufig werden Väterknoten zentriert über ihren Kinderknoten dargestellt. Dies ist vor allem dann sinnvoll, wenn die hierarchische Struktur
des Graphen in den Vordergrund gestellt werden soll. Durch die Zentrierung wird die Hierarchie sehr übersichtlich dargestellt. Das Kriterium kommt oft bei Baumstrukturen zum Einsatz.
Platzierung von Geschwisterknoten
Geschwisterknoten eines Baumes sollten sich auf einer einheitlichen
Höhe befinden. Das Kriterium führt zu übersichtlicheren Diagrammen,
da die Hierarchiestufen leichter erkennbar sind.
Symmetrie
Symmetrie in einer Zeichnung führt zur schnelleren Erfassung des dargestellten Sachverhaltes. Symmetrie ist aber nicht immer im geeigneten
Maße vorhanden bzw. ist sie schwer zu erfassen. Versucht man möglichst viel Symmetrie darzustellen, werden andere Kriterien vernachlässigt, z.B. entstehen oft zusätzliche Kantenkreuzungen.
Winkel zwischen den Kanten
Der Winkel zwischen zwei aufeinanderfolgenden Kanten an einem Knoten sollte möglichst groß sein, um die Kanten besser unterscheiden zu
können. Bei kleinen Winkeln ist die Unterscheidung der Kanten in der
Nähe des Knotens schwierig.
Verwendung der Zeichenfläche
Oft soll die benötigte Zeichenfläche möglichst klein gehalten werden.
Dieses Kriterium wird vor allem beim Schaltungsentwurf (VLSI) optimiert. Auch bei UML-Klassendiagrammen ist es vorteilhaft, kompakte
und somit leichter überschaubare Zeichnungen zu erstellen. Natürlich
müssen die Mindestabstände zwischen Knoten trotzdem eingehalten
werden. Das Kriterium wird teilweise schon durch die Kriterien „geringe Länge von Kanten“ und „geeigneter Knotenabstand“ realisiert.
Seitenverhältnis
Zeichnungen mit ausgewogenem Seitenverhältnis sind normalerweise
übersichtlicher als Zeichnungen, die übermäßig breit oder hoch sind.
Allerdings führen Hierarchistrukturen oft zu einem unausgewogenem
Seitenverhältnis, wenn man die hierarchische Struktur übersichtlich
darstellen will.
Orthogonalität
Bei einer orthogonalen Zeichnung werden die Kanten durch vertikale
28
KAPITEL 4. ÄSTHETIKKRITERIEN
und horizontale Segmente dargestellt. Orthogonale Zeichnungen wirken
meist sehr übersichtlich, auch wenn sie Kantenknicke enthalten. Die
Orthogonalität sorgt außerdem für die Einhaltung anderer Kriterien,
z.B. entstehen keine kleinen Winkel zwischen den Kanten.
4.2
Semantische Ästhetikkriterien
Neben den syntaktischen existieren auch semantische Ästhetikkriterien. Diese nehmen Bezug auf die Bedeutung der einzelnen Elemente des Graphen und
besitzen deshalb zusätzliche Informationen über die Elemente. Die semantischen Ästhetikkriterien sind deshalb stark vom Anwendungsbereich abhängig. Für Klassendiagramme sind u.a. folgende semantische Ästhetikkriterien
[12] verbreitet:
Richtung der Kanten
Ein Graph, der ein UML-Klassendiagramm repräsentiert, besteht aus
hierarchischen und nicht hierarchischen Kanten. Die hierarchischen
Kanten modellieren Vererbungs- und Implementierungsbeziehungen.
Solche Kanten werden oftmals in eine einheitliche Richtung gezeichnet, wodurch die Hierarchiestruktur besser zur Geltung kommt (vgl.
Abb. 4.1(b)).
Platzierung verwandter Elemente
Verwandte Elemente, die z.B. durch Komposition oder n-fach Assoziation entstehen, sollten möglichst nahe aneinander platziert werden.
Um die Lesbarkeit zu erhöhen, sollten Assoziationsklassen außerdem
möglichst nahe an der dazugehörigen Assoziationlinie stehen.
Platzierung von Erweiterungen
Erweiterungen und andere Beschriftungen sollten so platziert werden,
dass sie dem entsprechenden Element zugeordnet werden können und
sich möglichst nicht überlappen.
Darstellung der Vererbungshierarchie
In der UML existieren zwei Varianten für die Darstellung von Vererbungshierarchien. Entweder wird jede Vererbungsbeziehung durch eine
separate Vererbungslinie zwischen Super- und Subklasse symbolisiert,
oder die Vererbungslinien aller Subklassen einer Superklasse treffen sich
an einem Punkt und gehen dann gemeinsam zur Superklasse, wobei sie
eine Gabelform wie in Abb. 4.1(c) annehmen. Das Benutzen von Vererbungsgabeln führt zwar zu zusätzlichen Knicken, diese dienen aber
der übersichtlicheren Darstellung der Vererbungshierarchie.
Font und Textausrichtung
Die Textausrichtung kann horizontal, vertikal oder beliebig sein. Die
Wahl des Fonts spielt für den Algorithmus keine Rolle.
4.3. AUSWAHL GEEIGNETER ÄSTHETIKKRITERIEN
29
1
1
5
3
1
6
2
(a)
4
2
4
3
3
5
(b)
6
2
4
5
6
(c)
Abbildung 4.1: Verschiedene Zeichnungen eines Graphen. Die hierarchischen
Beziehungen kommen in den Zeichnungen (b) und (c) besser zur Geltung.
Die hier aufgezählten Ästhetikkriterien sind ausschließlich statische Kriterien. Dynamische Ästhetikkriterien nehmen Bezug auf die Veränderung
eines Diagramms, wenn sich der zugrundeliegende Graph ändert. Ein wichtiges dynamisches Kriterium ist die Minimierung der Veränderung der bestehenden Zeichnung („preserving the mental map“ [10]), wenn neue Elemente
hinzugefügt werden. Das Kriterium steht aber oft mit anderen in Konflikt,
z.B. mit der Minimierung der Anzahl der Kantenkreuzungen. Dynamisches
Graphzeichnen ist eine recht neue Disziplin und befindet sich noch in einem
Anfangsstadium.
Da Layouttools oft in interaktiven Anwendungen eingesetzt werden, müssen die verwendeten Algorithmen effizient sein. Viele der hier aufgezählten
Ästhetikkriterien sind aber NP-harte Optimierungsprobleme, wie die Kreuzungsminimierung eines allgemeinen Graphen [31]. Die meisten Algorithmen
sind deshalb Heuristiken, die oft eine gute Nährung aber meist keine optimale
Lösung bieten.
4.3
Auswahl geeigneter Ästhetikkriterien
In den letzten beiden Abschnitten wurden verschiedene syntaktische und semantische Ästhetikkriterien vorgestellt. In diesem Abschnitt sollen nun die
für Klassendiagramme geeignetsten ausgewählt und deren Priorität festgelegt werden. Dies ist notwendig, da sich wie gesehen, einige Kriterien wiedersprechen. Die Priorität legt die Wichtigkeit eines Ästhetikkriteriums gegenüber einem anderen fest. Das Kriterium mit der niedrigeren Priorität wird
nur insoweit angewendet, wie es das Kriterium mit der höheren Priorität
nicht negativ beeinflusst.
Es existieren verschiedene Studien, die die Auswirkungen von Ästhetikkriterien untersuchen. In [25] wurden die Auswirkungen von fünf verschiede-
30
KAPITEL 4. ÄSTHETIKKRITERIEN
nen syntaktischen Ästhetikkriterien auf die Lesbarkeit von Zeichnungen allgemeiner Graphen untersucht. Für die Untersuchung wurden Personen Fragen über die Graphen gestellt, wobei die Zeichnungen die Ästhetikkriterien
unterschiedlich stark berücksichtigten. Die Qualität einer Zeichnung wurde anhand der Beantwortungsgenauigkeit und -geschwindigkeit der Fragen
ermittelt. Ein Ästhetikkriterium wurde dann als nützlich angesehen, wenn
bei dessen Verwendung die Antwortgeschwindigkeit oder die Genauigkeit der
Antwort positiv beeinflusst wurde. Bei der Studie ging die Minimierung der
Anzahl der Kantenkreuzungen als das wichtigste Kriterium hervor. Auch die
Minimierung der Anzahl der Kantenknicke sowie die Maximierung der Symmetrie hatten Auswirkungen auf die Lesbarkeit. Für die Maximierung des
kleinsten Winkels zwischen Kanten und die Maximierung der Orthogonalität
wurden nur geringe Auswirkungen festgestellt.
Da die Bedeutung eines Ästhetikkriteriums vom jeweiligen Anwendungsgebiet abhängig ist, sind die Ergebnisse für allgemeine Graphen nicht automatisch auch auf Klassendiagramme übertragbar. Die von Benutzern bevorzugten Ästhetikkriterien bezüglich Klassendiagrammen wurden in [26] ermittelt. Dazu mussten Versuchspersonen jeweils von zwei alternativen Darstellungen eines Graphen, die von ihnen bevorzugte Darstellung wählen. Tabelle
4.1 zeigt einen Auszug des Ergebnisses der Untersuchung. Wie zu sehen ist,
Ästhetik
Bevorzugung (in %)
weniger Kantenkreuzungen
93%
weniger Kantenknicke
91%
nur horizontale Beschriftungen
86%
Vererbungsgabeln
76%
kompaktere Zeichnung
73%
mehr Orthogonalität
61%
Tabelle 4.1: Ästhetik Präferenzen für Klassendiagramme
(Auszug aus [26])
gingen auch hier die Kriterien „Minimierung der Anzahl der Kantenknicke“
und „Minimierung der Anzahl der Kantenkreuzungen“ als die wichtigsten
Kriterien hervor.
Ein in [28] beschriebenes Experiment, verwendete einen anderen Ansatz
zur Ermittlung der wichtigsten Ästhetikkriterien von Klassendiagrammen.
Wie bei der Studie über syntaktische Ästhetikkriterien, mussten Versuchspersonen Fragen zu bestehenden Klassendiagrammen beantworten, die ein
Kriterium in einem bestimmten Maß erfüllten. Je nach Genauigkeit und Geschwindigkeit der Beantwortung wurde dann auf die Wichtigkeit eines Kriteriums geschlossen. Das Experiment zeigte, dass die von Versuchspersonen
bevorzugten Kriterien nicht unbedingt zu einer höheren Lesbarkeit führen,
4.3. AUSWAHL GEEIGNETER ÄSTHETIKKRITERIEN
31
die statistisch nachweisbar ist. Für die Knotenverteilung, die Kantenlänge,
die Symmetrie, die Richtung der Kanten und die Orthogonalität konnten
keine Auswirkungen nachgewiesen werden. Für die Anzahl der Kantenknicke
entsprach das Ergebnis den Erwartungen. Weniger Knicke wirkten sich positiv auf die Lesbarkeit eines Diagramms aus. Die Ergebnisse des Experiments
führten zu der Annahme, dass die Wichtigkeit vieler Ästhetikkriterien stark
von der semantischen Gruppierung von verwandten Objekten abhängt. Bei
verwandten Objekten ist es z.B. wichtiger, diese nahe beieinander zu platzieren, als auf möglichst viel Symmetrie zu achten.
In der Praxis tauchen in Klassendiagrammen viele Notationsvarianten
auf. In [27] wurde untersucht, welche Varianten von Anwendern bevorzugt
werden. Dabei wurde unter anderem festgestellt, dass nahezu alle Versuchspersonen eine Aufwärtszeichnung der Vererbungskanten (alle Kanten zeigen nach oben) als intuitiver beurteilten. Die meisten Personen bevorzugten
außerdem die Verwendung von Vererbungsgabeln zum Zeichnen von Vererbungshierarchien, da sie diese bei größeren Diagrammen übersichtlicher fanden. Die Ergebnisse zeigten aber auch, dass die Benutzer bei diesen Varianten
mehr Fehler bei der Beantwortung von Fragen zu den Klassendiagrammen
gemacht haben als bei den Alternativen. Das wurde damit erklärt, dass die
Alternativen wohl weniger intuitiv waren und die Benutzer sich daher stärker konzentrieren mussten. Dieses Ergebnis sollte jedoch nicht dazu führen,
Zeichnungen absichtlich schwer zugänglich zu machen.
Für den zu entwickelten Layoutalgorithmus wurden aufgrund der Erkenntnisse der Studien folgende Ästhetikkriterien als Eckpfeiler gewählt:
1. Orthogonalität
2. Verwenden von Vererbungsgabeln
3. einheitliche Kantenrichtung (upward planarity)
4. einheitliche Höhe von Geschwisterknoten bei der Vererbung
5. wenige Kantenkreuzungen
6. wenige Kantenknicke
Bei syntaktischen Graphen spielt die Maximierung der Orthogonalität noch
keine Rolle. Bei semantischen Graphen gewinnt sie jedoch an Bedeutung [26].
Eine orthogonale Zeichnung sorgt dafür, dass die Winkel zwischen den Kanten nicht zu klein sind. Für orthogonale Zeichnungen existieren außerdem
Algorithmen, die nur wenige Kreuzungen und Knicke produzieren. Dadurch
bietet sich ein orthogonaler Ansatz für den zu entwickelnden Layoutalgorithmus an. Die Verwendung von Vererbungsgabeln und einer einheitlichen
Kantenrichtung wird von vielen Benutzern bevorzugt. Durch die einheitliche
Kantenrichtung werden Vererbungsstrukturen besonders übersichtlich dargestellt. Beide Kriterien beziehen sich nur auf eine bestimmte Kantenmenge.
32
KAPITEL 4. ÄSTHETIKKRITERIEN
Die Ästhetikkriterien „Minimierung der Anzahl von Kantenkreuzungen“ und
„Minimierung der Anzahl von Kantenknicken“ gingen aus den obigen Studien
als die wichtigsten Kriterien hervor. Das Kriterium „einheitlichen Höhe von
Geschwisterknoten“ wurde in keiner der Studien untersucht. Die Anwendung
des Kriteriums ist aber gerade bei Vererbungsstrukturen wünschenswert. Da
die bevorzugten Ästhetikkriterien auch immer individuell vom Benutzer abhängen, sollte der Layoutalgorithmus möglichst flexibel sein und eine Anpassung an bestimmte Kriterien ermöglichen.
Die Priorität der gewählten Ästhetikkriterien entspricht der aufgezählten
Reihenfolge, d.h. jede Zeichnung ist auf jeden Fall orthogonal. Die Kriterien
„Benutzen von Vererbungsgabeln“ und „einheitliche Kantenrichtung“ werden
angewendet, obwohl sie zu mehr Kreuzungen und Knicken führen können.
Das Kriterium „einheitliche Höhe von Geschwisterknoten“ wird nur angewendet, falls dadurch die einheitliche Kantenrichtung erhalten bleibt.
Kapitel 5
Der Topology-Shape-Metrics
Ansatz
Dem zu entwickelnden Layoutalgorithmus für UML-Klassendiagramme soll
ein orthogonaler Ansatz zugrundeliegen, der auf dem sogenannten TopologyShape-Metrics Ansatz basiert. Der Topology-Shape-Metrics Ansatz wird im
folgenden Abschnitt erläutert. Anschließend werden existierende Algorithmen vorgestellt, die den Topology-Shape-Metrics Ansatz realisieren. Im nächsten Kapitel werden diese Algorithmen dann entsprechend modifiziert, um
die spezifischen Anforderungen, die sich für Klassendiagramme ergeben, zu
integrieren.
Für einen nicht zusammenhängenden Graph G, wird der Layoutprozess
für alle Zusammenhangkomponenten von G ausgeführt. Nach dem Layouten
der einzelnen Komponenten, werden diese dann zum Gesamtlayout zusammengesetzt. Im folgenden kann also immer von einem zusammenhängenden
Eingabegraph für die einzelnen Algorithmen ausgegangen werden.
5.1
Definition
Für das Zeichnen von Graphen existieren verschiedene Paradigmen. Beim
orthogonalen Graphzeichnen wird gewöhnlich der Topology-Shape-Metrics
Ansatz [32] verwendet, der den Layoutvorgang eines Graphen in folgende
drei Phasen unterteilt:
1. In der ersten Phase wird die Topologie (topology) des Graphen festgelegt. Die Topologie beschreibt die Anordnung der Graphelemente.
Zwei Graphen besitzen die gleiche Topologie, wenn der eine durch Umformung in den anderen überführt werden kann, ohne dass dabei die
Kantenordnung um die Knoten und somit die Faces verändert werden.
Die Topologie eines Graphen wird durch die planare Repräsentation
beschrieben, welche aus einer ebenen Einbettung des Graphen abgeleitet werden kann. Die Phase wird deshalb auch oft als Einbettung
34
KAPITEL 5. DER TOPOLOGY-SHAPE-METRICS ANSATZ
bezeichnet. Nicht planare Graphen werden planarisiert, indem Kantenkreuzungen durch Knoten ersetzt werden.
2. In der zweiten Phase wird die Form (shape) des Graphen festgelegt.
Die Form wird durch die Angabe der Kantenknicke und den Winkeln
zwischen den Kanten angegeben. Zwei Graphen besitzen die gleiche
Form, wenn sie die gleiche Topologie besitzen und man sie durch Veränderung der Kantenlängen (und Knotengröße) ineinander überführen
kann. Möchte man eine orthogonale Zeichnung erzeugen, so nennt man
diese Phase Orthogonalisierung. Die Form wird dann durch die orthogonale Repräsentation beschrieben.
3. In der dritten Phase wird die Metrik (metric) bestimmt. Die Metrik
legt die Größe der Knoten und die Länge der Kanten fest. Zwei Graphen besitzen die gleiche Metrik, falls sie die gleiche Topologie und
Form besitzen und bis auf Translation und Rotation identisch zueinander sind. Beim orthogonalen Graphzeichnen wird die Metrik durch
die Kompaktierung bestimmt, wodurch dann eine orthogonale Gittereinbettung entsteht. Vor der Kompaktierung müssen die bei der Planarisierung hinzugefügten Knoten wieder entfernt werden.
Die Topologie, die Form und die Metrik sind charakteristische Eigenschaften von Gitterzeichnungen. Die einzelnen Phasen werden durch verschiedene
Algorithmen realisiert, die verschiedene Ästhetikkriterien fokusieren. Jede
Kreuzung, die in der ersten Phase erzeugt wird, wird durch einen künstlichen Knoten repräsentiert. Zuviele solcher Kreuzungsknoten führen oft zu
schlechteren Layoutresultaten. In der ersten Phase wird deshalb gewöhnlich
ein Algorithmus eingesetzt, der möglichst wenig Kantenkreuzungen erzeugt.
Das Hinzufügen oder Entfernen einer Kantenkreuzung bedeutet auch immer ein Ändern der Topologie. Für die zweite Phase wird gewöhnlich ein
Algorithmus verwendet, der die Anzahl der Kantenknicke minimiert. Dieses
Ästhetikkriterium kann erst in der zweiten Phase berücksichtigt werden, da
die erste Phase keine Form und somit auch keine Knicke kennt. In der dritten
Phase wird gewöhnlich ein Algorithmus eingesetzt, der die Fläche minimiert.
Eine orthogonale Zeichnung wird also Schritt für Schritt aufgebaut. Das
bedeutet auch, dass jede Phase auf das Ergebnis der vorausgegangenen Phase
aufsetzt. Dies hat u.a. zur Folge, dass die Minimalität der Kantenknicke
nur bezüglich der gegebenen Topologie und damit mit bereits festgelegten
Kantenkreuzungen bestimmt wird. Durch die Aufteilung in unterschiedliche
Phasen, erhält man eine gewisse Unabhängigkeit bei der Algorithmenwahl
für eine Phase.
5.2. EINBETTUNG
5.2
35
Einbettung
Um die erste Phase des Topology-Shape-Metrics Ansatz zu realisieren, muss
eine planare Repräsentation P für den Eingabegraph G gefunden werden.
Da Graphen, die UML-Klassendiagramme modellieren, im allgemeinen nicht
planar sind, müssen diese erst planar gemacht werden. Diesen Vorgang nennt
man Planarisierung. Sie basiert darauf, dass ein Graph, der nicht planar ist,
dadurch planar gemacht werden kann, dass jede Kantenkreuzung durch einen
Knoten ersetzt wird (vgl. Abb. 5.1). Alle gerichteten Kanten ED des teilgerichteten Eingabegraphen G = (V, ED ∪EU ) sollen aufwärtsgerichtet gezeichnet werden und müssen deshalb aufwärtsplanar eingebettet werden. Der von
der Kantenmenge ED induzierte Subgraph von G muss dazu azyklisch sein.
c
Abbildung 5.1: Ersetzung einer Kantenkreuzung durch einen Knoten.
Der hier vorgestelle Planarisierungsalgorithmus geht folgendermaßen vor:
Zuerst werden Selbstschleifen und Mehrfachkanten aus dem Eingabegraph G
entfernt. Beim Entfernen von Mehrfachkanten muss darauf geachtet werden,
dass die bleibende Kante eine gerichtete ist, falls eine solche existiert. Ansonsten könnte eine gerichtete Mehrfachkante eventuell nicht aufwärtsplanar
eingebettet werden. Für den zu planarisierenden Graphen G = (V, E) wird
zunächst ein maximaler planarer Subgraph GSub = (V, F ) gesucht, wobei
gilt: F ⊆ E. Nach dem Bestimmen des maximalen planaren Subgraphs,
werden die entfernten Mehrfachkanten und Selbstschleifen sowie die Restkanten, die nicht in GSub enthalten sind, so in den Subgraphen eingefügt,
dass möglichst wenige Kreuzungen entstehen und alle gerichteten Kanten
aufwärtsplanar sind. Zwar ist das Problem des Findens eines maximalen planaren Subgraphen für allgemeine Graphen NP-vollständig, es existieren aber
verschiedene Heuristiken, die gute Ergebnisse liefern. Die hier beschriebene
Heuristik ist die von Goldschmidt und Takvorian (GT-Heuristik) [21].
5.2.1
GT-Heuristik
Die GT-Heuristik besteht aus zwei Phasen. In der ersten Phase wird eine
Knotenfolge ermittelt, die alle Knoten des Eingabegraphen enthält. Stellt
man sich die Knotenfolge auf einer Linie angeordnet vor, dann versucht die
zweite Phase die maximale Anzahl sich nicht überschneidender Kanten F
36
KAPITEL 5. DER TOPOLOGY-SHAPE-METRICS ANSATZ
zu finden, die über oder unter der Linie angeordnet werden können (vgl.
Abb. 5.2). Es entstehen dabei zwei disjunkte Kantenmengen A ⊆ E und
B ⊆ E, für die gilt: |A| + |B| ist maximal und kein Kantenpaar aus A bzw.
B schneidet sich bezüglich der Knotenfolge. Es gilt also F = A ∪ B. Sei
π : V → N die Funktion, die die Position eines Knotens in der Knotenfolge
angibt. Zwei Kanten (u, v) mit π(u) < π(v) und (w, x) mit π(w) < π(x)
schneiden sich bezüglich der Knotenfolge, falls π(w) < π(u) < π(x) < π(v)
oder π(u) < π(w) < π(v) < π(x). Die Mengen A und B werden auch als
Maximum Independent Sets (MIS) bezeichnet. Die Restkanten R = E \ F
müssen später, in einem extra Schritt, in den Subgraphen eingefügt werden.
2
3
1
4
5
5
3
4
2
1
6
6
(a)
(b)
Abbildung 5.2: Darstellung eines Graphen (a) und dem dazugehörigen Ergebnis der GT-Heuristik (b) (aus [17]).
Die Anordnung der Knoten in der ersten Phase hat einen erheblichen
Einfluss auf die Anzahl der Kanten in F und somit auf die Qualität der gefundenen Lösung. Falls die Knotenfolge einen Hamilton-Zyklus1 bildet, enthält der gefundene planare Subgraph, nach [21], mindestens 43 der Anzahl
der Kanten des optimalen planaren Subgraphen. Das Finden eines HamiltonZyklus in einem Graphen ist allerdings ein NP-vollständiges Problem. In [21]
wird der folgende Greedy-Algorithmus vorgestellt, der eine gute Knotenfolge
liefert, auch wenn damit nur selten ein Hamilton-Zyklus gefunden wird: Der
erste Knoten v1 der Knotenfolge ist immer ein Knoten mit kleinstem Grad
in G. Sei (v1 , .., vk ) 0 ≤ k ≤ |V | − 1 die Knotenfolge nachdem k Knoten ausgewählt worden sind und Gk = (Vk , Ek ) der Subgraph der durch die Knoten
V \ {v1 , .., vk } induziert wird. Der Knoten vk+1 ∈ Vk ist dann entweder ein
Nachbarknoten von vk mit kleinstem Grad bezüglich Gk oder falls vk keinen
Nachbarknoten besitzt, ein Knoten mit kleinstem Grad bezüglich Gk .
1
Ein Hamilton-Zyklus ist ein einfacher Pfad von G, der alle Knoten beinhaltet.
5.2. EINBETTUNG
37
Da gerichtete Kanten e ∈ ED existieren, die aufwärts gezeichnet werden sollen, muss die erste Phase der Heuristik noch wie in [17] beschrieben
modifiziert werden. Für alle gerichteten Kanten (u, v) ∈ ED muss gelten
π(u) < π(v). Um dies zu erreichen, wird eine Fehlerfunktion : V → N
auf den Knoten definiert, die für jeden Knoten v ∈ V die Anzahl der eingehenden, gerichteten Kanten angibt, die sich in Ek befinden. Ein Knoten
v ∈ V darf nun nur in die Knotenfolge aufgenommen werden, falls (v) = 0.
Ansonsten existieren Knoten u ∈ V mit (u, v) ∈ ED , die die Bedingung
π(u) < π(v) verletzten würden. Die so berechnete Knotenfolge stellt eine
topologische Sortierung von G dar.
Die Maximum Independent Sets, die in der 2. Phase bestimmt werden,
sind normalerweise maximal bezüglich der Anzahl der enthaltenen Kanten.
Für teilgerichtete Graphen bietet es sich jedoch an, die Maximum Independent Sets maximal bezüglich der Summe der Gewichte der enthaltenen Kanten zu machen. Dazu wird eine Gewichtsfunktion weight : E → N auf den
Kanten eingeführt. Da das spätere Einfügen von gerichteten Kanten einen erheblich größeren Aufwand erfordert, können diese nun durch ein höheres Gewicht bevorzugt werden. Die Maximum Independent Sets enthalten dadurch
möglichst viele gerichtete Kanten, allerdings besitzen sie im allgemeinen keine maximale Anzahl von Kanten mehr, so dass die Anzahl der Restkanten
R zunimmt, auch wenn R dann weniger gerichtete Kanten enthält.
Eine deutliche Verbesserung der GT-Heuristik kann durch die in [29] vorgestellte Randomisierung erzielt werden. In der ersten Phase der Heuristik
wird stets ein Knoten mit kleinstem Grad gewählt und in die Knotenfolge
eingefügt. Häufig kommt es vor, dass mehrere Knoten mit kleinstem Grad
existieren. Wählt man den einzufügenden Knoten aus der Menge der möglichen Knoten zufällig, dann unterscheidet sich die Knotenfolge bei mehrmaliger Berechnung. Wird die zweite Phase für verschiedene Knotenfolgen
durchführt, verändert sich auch deren Ergebnis. Durchläuft man die randomisierte GT-Heuristik k mal, erhält man also unterschiedliche Ergebnisse.
Ein neues Ergebnis wird nur abgespeichert, wenn es bezüglich der Summe
der Gewichte bzw. bezüglich der Anzahl der Kanten, die in den Maximum
Independent Sets enthalten sind, besser als das alte Ergebnis war. In den
meisten Fällen ist das so erzielte Ergebnis deutlich besser. Die Laufzeit der
Heuristik steigt dabei um den Faktor k.
Die Laufzeit der ersten Phase beträgt O(|V |2 +|E|), die der zweiten Phase
O(|V ||E|2 ) mit oder ohne Gewichtung [14]. Wendet man die Randomisierung
an und wählt k konstant, erhöht sich die Laufzeit bezüglich der O-Notation
nicht. Die Gesamtlaufzeit beträgt also weiterhin O(|V ||E|2 ). Die Heuristik
liefert sehr gute Ergebnisse bezüglich der Größe des gefundenen planaren
Subgraphen [5]. Allerdings ist sie aufgrund ihrer Laufzeit eher für kleine bis
mittelgroße Graphen geeignet, was aber für UML-Klassendiagramme ausreichen sollte. Für den gefundenen planaren Subgraph GSub muss nun noch
wie in [17] beschrieben, die zyklische Kantenordnung um die Knoten be-
38
KAPITEL 5. DER TOPOLOGY-SHAPE-METRICS ANSATZ
stimmt werden. Nun erhält man einen eben eingebetteten, aufwärtsplanaren
Subgraph mit der planaren Repräsentation PSub .
5.2.2
Routen von Kanten
Die Restkanten R, die nicht im planaren Subgraph GSub enthalten sind,
müssen nun mit möglichst wenig Überkreuzungen und unter Beibehaltung
der Aufwärtsplanarität in GSub eingefügt werden. Dieser Vorgang wird als
Routen der Kanten bezeichnet. Die Menge der gerichteten Restkanten wird
dabei mit RD und die Menge der ungerichteten Kanten mit RU bezeichnet.
Die nun vorgestellte Vorgehensweise stammt aus [14] und [17].
Routen von aufwärtsgerichteten Kanten
Jede gerichtete Kante (v, w) ∈ RD muss als monoton steigende Kurve zwischen ihrem Startknoten v und ihrem Endknoten w gezeichnet werden, wobei
möglichst wenige Kreuzungen enstehen sollen. Um dies zu erreichen, muss
der Graph GSub zunächst zu einem st-Graph Gst erweitert werden.
Definition 3 (st-Graph) Ein st-Graph ist ein gerichteter, azyklischer Graph
mit genau einer Quelle s und einer Senke t.
Eine Quelle s ist ein Knoten für den δin (s) = 0, eine Senke t ist ein Knoten
für den δout (t) = 0.
Satz 2 Sei G ein gerichteter Graph. Folgende Aussagen sind äquivalent:
• G ist aufwärtsplanar.
• G erlaubt eine aufwärtsplanare, geradlinige Zeichnung.
• G ist der aufspannende Subgraph eines planaren st-Graphen.
Der Beweis zu diesem Satz findet sich in [9]. Aus dem Satz folgt, dass jeder
Graph G, der aufwärtsplanar ist, auch zu einem st-Graphen erweitert werden
kann.
Für eine Aufwärtseinbettung von GSub besteht die Erweiterung zu Gst
darin, dass unerwünschte Senken und Quellen durch Hinzufügen von Kanten entfernt werden. Dies geschieht mit Hilfe der Knotenfolge, die in der
ersten Phase der GT-Heuristik berechnet wurde. Die zusätzlich hinzugefügten Kanten werden Augmentierungskanten genannt. Sie werden nach dem
Routen der aufwärtsgerichteten Kanten wieder aus dem Graphen entfernt.
Der st-Graph Gst wird zur Levelisierung der Knoten von GSub eingesetzt.
Dazu wird eine Funktion level : V → N eingeführt, die jedem Knoten eine
Höhe zuweist. Die Höhe level(v) eines Knotens v in Gst ist die Länge des maximalen Pfades vom Knoten s zum Knoten v. Damit die Zuweisung korrekt
5.2. EINBETTUNG
39
ist, müssen auch die Kanten berücksichtigt werden, die nicht in GSub enthalten sind. Ansonsten zerstört man eventuell einen längsten Pfad. Außerdem
muss jede ungerichtete Kante temporär gerichtet werden. Die Richtung der
Kanten muss dabei so gewählt werden, dass keine Zykel in Gst entstehen,
da sonst keine Höhenzuweisung möglich ist. Man wählt die Richtung einer
Kante deswegen so, dass sich ihr Startknoten, bezüglich der Knotenfolge,
die in der 1. Phase der GT-Heuristik berechnet wurde, vor dem Endknoten
befindet. Da die Knotenfolge dann eine topologische Sortierung von Gst darstellt, ist Gst zykelfrei. Nach der Levelisierung wird die temporäre Richtung
der ungerichteten Kanten wieder aufgehoben. Um eine Kante (v, w) ∈ RD
aufwärtsplanar einbetten zu können, muss gelten level(v) < level(w).
Eine aufwärtsplanare Einbettung eines st-Graphen besitzt folgende Eigenschaften:
• Der Knoten s ist der niedrigste und der Knoten t ist der höchste Knoten
und beide liegen am äußeren Face.
• Jedes Face f besitzt für sich betrachtet selbst eine Quelle sf und eine
Senke tf .
• Da keine horizontalen Kanten in einer Aufwärtseinbettung erlaubt sind,
geht ein Face über mindestens 2 Ebenen (von Mehrfachkanten abgesehen).
Um eine Kante (v, w) ∈ RD aufwärtsplanar in den Graphen Gst zu routen, wird nun ein Routinggraph GRouting = (VRouting , ERouting ) aufgebaut,
auf dessen Kantenmenge eine Funktion cost : ERouting → {0, 1} definiert
wird, die den Kanten Kosten zuweist.
Sei Ebene i der Teilraum zwischen level i und level i + 1. Der Routinggraph GRouting eines st-Graphen Gst wird folgendermaßen erstellt (vgl.
Abb. 5.3):
• Für jedes innere Face f von Gst wird, für jede von f überdeckte Ebene
i, ein Knoten vf,i erzeugt. Die aufeinanderfolgenden Knoten von f
werden durch gerichtete Kanten (vf,i , vf,i+1 ) verbunden, die die Kosten
0 besitzen.
• Das äußere Face fout von Gst wird im Routinggraph durch ein linkes
und ein rechtes äußeres Face dargestellt, welche mit fout,l bzw. fout,r bezeichnet werden. Für jede Ebene i werden Knoten vfout,r ,i bzw. vfout,l ,i
erzeugt. Die aufeinanderfolgenden Knoten eines Repräsentanten werden wiederum jeweils durch eine gerichtete Kante verbunden, die die
Kosten 0 besitzt.
• Alle Knoten vf,i und vg,i zweier benachbarter Faces f und g, die sich
auf der selben Ebene i befinden, werden durch die gerichteten Kanten
40
KAPITEL 5. DER TOPOLOGY-SHAPE-METRICS ANSATZ
(vf,i , vg,i ) und (vg,i , vf,i ) verbunden. Diese Kanten besitzen die Kosten
0, falls die abgrenzende Kante eine Augmentierungskante ist und die
Kosten 1 sonst. Diese Unterscheidung hat folgenden Grund: Eine Augmentierungskante kann zwar an einer Kreuzung in Gst beteiligt sein,
nach dem Einfügen der Restkanten werden die Augmentierungskanten aber wieder entfernt, wodurch eine Augmentierungskante niemals
Kreuzungen im Graph G erzeugen kann.
Nach dieser Konstruktion ist ein Routinggraph immer planar.
level 6
10
Ebene 5
6
7
8
level 5
9
level 4
Ebene 4
Ebene 3
5
level 3
4
level 2
Ebene 2
Ebene 1
3
2
level 1
Ebene 0
1
level 0
Abbildung 5.3: Darstellung eines st-Graphen und dessen Routinggraph.
Nachdem der Routinggraph GRouting von Gst erstellt wurde, müssen noch
die Knoten v 0 und w0 in diesen eingefügt werden, welche die Knoten v und w
der einzufügenden Kante (v, w) repräsentieren. Der Knoten v 0 wird mit allen
Knoten im Routinggraph verbunden, die auf der Ebene level(v) liegen und
ein an v angrenzendes Face repräsentieren. Die entstehenden Kanten besitzen
die Kosten 0. Der Knoten w0 wird analog mit den Knoten verbunden, die auf
der Ebene level(w) − 1 liegen.
Die Kosten des billigsten Weges zwischen den Knoten v 0 und w0 im Routinggraph entspricht nun der minimalen Anzahl von Überkreuzungen der
einzufügenden Kante im Graph G unter Berücksichtigung der Aufwärtsplanarität. Die Kante wird nun entlang des billigsten Weges in Gst eingefügt.
Dazu muss die Kantenordnung an den Knoten v und w aktualisiert und für
5.2. EINBETTUNG
41
jeden entstandenen Kreuzungsknoten die zyklische Kantenordnung angegeben werden. Beim Einfügen einer Kante steigt die Anzahl der Knoten von
Gst demnach um die Anzahl der Kantenkreuzungen. Bevor die nächste Kante in Gst eingefügt werden kann, werden die Knoten v 0 und w0 wieder aus
dem Routinggraph entfernt. Außerdem muss der Routinggraph aktualisiert
werden, da sich der zugrundeliegende Graph Gst geändert hat. Die Laufzeit
für das Einfügen der Kanten aus RD beträgt O |RD | · (|V | + c)2 , wobei
c die Gesamtzahl der Kantenkreuzungen bezeichnet. Die Berechnung eines
billigsten Pfades in einem planaren Graphen G = (V, E) mit nicht-negativen
Kantenkosten kann dabei in O(|V |) erfolgen [23].
Routen von ungerichteten Kanten
Nachdem die gerichteten Kanten in Gst eingefügt worden sind und die Augmentierungskanten entfernt wurden, müssen nun die Kanten aus RU mit
möglichst wenig Kreuzungen in GSub 2 eingefügt werden. Da diese nicht monoton steigend eingefügt werden müssen, vereinfacht sich der Einfügevorgang
erheblich. Zum Finden einer kreuzungsminimalen Route einer ungerichteten
Kante, kann der duale Graph von GSub verwendet werden.
Definition 4 (dualer Graph) Sei G = (V, E) ein eben eingebetteter Graph
und F die Menge der Faces von G. Für den dualen Graph GD = (V 0 , E 0 )
von G gilt:
• Für jedes Face f ∈ F existiert ein Knoten in V 0 .
• Für jede Kante e ∈ E existiert eine ungerichtete Kante in E 0 , zwischen
den beiden Knoten aus V 0 , die die, durch die Kante e getrennten, Faces
repräsentieren.
Der duale Graph GD eines eben eingebetteten Graphen G ist also ungerichtet,
zusammenhängend und planar.
Der duale Graph von GD ist zum Graphen G isomorph. Wenn zwei Faces
von G mehrere Kanten gemeinsam haben, entstehen Mehrfachkanten in GD .
Selbstschleifen in GD werden durch Brücken in G verursacht (vgl. Abb. 5.4).
Um nun eine Kante (v, w) ∈ RU zu routen, muss der duale Graph von
GSub erstellt werden. Auf den Kanten des dualen Graphen wird eine Kostenfunktion definiert, wobei alle Kanten die Kosten 1 besitzen. Jetzt werden,
wie im aufwärtsgerichteten Fall, die Stellvertreterknoten v 0 und w0 in den
dualen Graph eingefügt. Den Knoten v 0 bzw. w0 verbindet man mit den
Knoten des dualen Graphen, die die Faces repräsentieren, die an den Knoten v bzw. w angrenzen. Die dabei enstandenen Kanten besitzen die Kosten
2
GSub bezeichnet jetzt den Graphen, der durch die Entfernung der Augmentierungskanten aus Gst entstanden ist.
42
KAPITEL 5. DER TOPOLOGY-SHAPE-METRICS ANSATZ
2
1
7
3
4
5
6
Abbildung 5.4: Darstellung eines Graphen und dem dazugehörigen dualen
Graph.
0. Berechnet man nun den billigsten Weg zwischen den Knoten v 0 und w0 ,
dann entsprechen dessen Kosten der minimalen Anzahl von Kreuzungen, die
beim Einfügen der Kante (v, w) in den Graphen GSub entstehen. Beim Einfügen muss analog zum aufwärtgerichteten Fall, die zyklische Kantenordnung
der betreffenden Knoten aktualisiert werden. Die
Laufzeit für das Einfügen
der Kanten aus RU beträgt O |RU | · (|V | + c) .
Nachdem sämtliche Kanten aus RU eingefügt wurden, erhält man eine
aufwärtsplanare Einbettung des Graphen GSub . Dieser stellt nun eine Erweiterung des Graphen G dar, da er zusätzlich die entstandenen Kreuzungsknoten enthält. Auch für planare Graphen kann die gefundene ebene Einbettung
Kreuzungen besitzen. Diese entstehen durch eine ungünstige Wahl des planaren Subgraphen oder durch ungünstige Kantenrouten. Da |RD | = O(|E|),
ergibt sich für die gesamte Einbettung eine Laufzeit von:
5.2.3
O |V ||E|2 + |E| · (|V | + c)2 .
Rerouting von Kanten
Restkanten werden nacheinander in den planaren Subgraphen eingefügt.
Auch wenn jede Kante zum Zeitpunkt des Einfügens knickminimal geroutet
wird, kann sich die Wahl einer Route im nachhinein als ungünstig erweisen.
Die Entscheidung für eine Route beeinflusst die möglichen Routen der noch
einzufügenden Kanten. Man kann also nicht sagen, ob die Route einer Kante auch im Hinblick auf die noch einzufügenden Kanten optimal ist. Durch
das Rerouting können schlechte Entscheidungen bei der Routenwahl noch im
nachhinein korrigiert werden. Dazu werden Kanten, die Kreuzungen verursachen, aus dem Graph entfernt, neu geroutet und wieder eingefügt. Durch das
Rerouting von Kanten kann die Anzahl der Kantenkreuzungen im Graphen
reduziert werden.
5.3. ORTHOGONALISIERUNG
43
Kanten mit vielen Kreuzungen besitzen das größte Verbesserungspotential, deshalb beginnt man beim Rerouting mit solchen Kanten. Die Anzahl
der Rerouting-Durchläufe sollte begrenzt werden, da Graphen mit vielen
Kreuzungen sonst eine sehr hohe Laufzeit verursachen würden, da sich beim
Rerouten einer Kante auch die Anzahl der Kantenkreuzungen anderer Kanten ändert.
Um eine Kante neu zu routen, muss zuerst der duale Graph bzw. der
Routinggraph erzeugt werden. Dann wird nach einer besseren Route für die
Kante gesucht. Wird eine bessere Route gefunden, dann wird die Kante aus
dem Graphen entfernt und auf der neuen Route wieder eingefügt.
5.3
Orthogonalisierung
Nachdem eine planare Repräsentation P für den Graphen G gefunden wurde,
muss diese nun zu einer orthogonalen Repräsentation H erweitert werden.
Dazu muss die Form des Graphen bestimmt werden. Um eine übersichtliche
Zeichnung zu erhalten, sollten dabei möglichst wenig Knicke entstehen.
5.3.1
Tamassias Algorithmus
In diesem Abschnitt wird ein von Tamassia [30] entwickelter, kombinatorischer Algorithmus vorgestellt, der in der Lage ist, eine knickminimale orthogonale Repräsentation eines planaren 4-Graphen mit gegebener planarer
Repräsentation zu berechnen. Dabei werden die Knoten des Graphen als
Punkte auf einem orthogonalen Gitter angesehen (vgl. Abb. 2.3). Tamassias
Algorithmus ermittelt die knickminimale orthogonale Repräsentation durch
das Lösen eines Min-Cost-Flow-Problems.
Abbildung auf ein Min-Cost-Flow-Problem
Im folgenden sei G = (V, E) ein planarer 4-Graph und P dessen planare Repräsentation. Es wird nun ein Netzwerk N (P ) = (VN , EN ) aus der planaren
Repräsentation P konstruiert, aus dessen minimalen Kostenfluss eine knickminimale orthogonale Repräsentation abgeleitet werden kann. Dazu wird auf
den Kanten des Netzwerks eine Kosten- und Kapazitätsfunktion definiert.
Für die Knotenmenge des Netzwerkes VN gilt: VN = {s} ∪ {t} ∪ UV ∪ UF , wobei s die Quelle und t die Senke des Netzwerks bezeichnet. Die Knotenmenge
UV enthält einen Knoten uv für jeden Knoten v ∈ V und die Knotenmenge
UF enthält einen Knoten uf für jedes Face f von G. Die Kantenmenge EN
setzt sich aus folgenden Kanten zusammen:
• Kanten (s, uv ) wobei gilt: uv ∈ UV . Die Kanten haben die Kosten 0
und die Kapazität 4 − δ(v) (vgl. Abb. 5.5(a)).
44
KAPITEL 5. DER TOPOLOGY-SHAPE-METRICS ANSATZ
• Kanten (s, uf ) wobei gilt: uf ∈ UF und f ist ein inneres Face von G mit
δ(f ) ≤ 3. Die Kanten haben die Kosten 0 und die Kapazität 4 − δ(f ).
• Kanten (uf , t) wobei gilt: uf ∈ UF und f ist entweder das äußere Face
von G oder ein inneres Face mit δ(f ) ≥ 5. Die Kanten haben die Kosten
0 und die Kapazität δ(f ) + 4, falls f das äußere Face ist bzw. δ(f ) − 4
sonst (vgl. Abb. 5.5(b)).
• Kanten (uv , uf ) wobei gilt: uv ∈ UV , uf ∈ UF und v ist ein Endpunkt einer Kante aus P (f ). Die Kanten haben die Kosten 0 und die
Kapazität ∞ (vgl. Abb. 5.5(c)).
• Kanten (uf , ug ) und (ug , uf ) wobei gilt: uf , ug ∈ UF und die Faces f
und g besitzen mindestens eine gemeinsame Kante. Besitzt ein Face f
eine Brücke, so ensteht eine Selbstschleife (uf , uf ). Die Kanten haben
die Kosten 1 und die Kapazität ∞ (vgl. Abb. 5.5(d)).
Interpretation des Flusses
Für den Flusswert |f | des Netzwerkes N (P ) gilt:
|f | =
X
cap(s, v) =
v∈VN
X
(5.1)
cap(w, t).
w∈VN
Die Gleichheit folgt aus der Eulerschen Formel, da

X
w∈VN
cap(w, t) −
X
v∈VN


 X 
cap(s, v) = 
δ(f
)
−
4
+
δ(f
)
+
4
out


f ∈F \fout
∧ δ(f )≥5


X
 X 
−
4
−
δ(f
)
+
4
−
δ(v)


f ∈F \fout
∧ δ(f )≤3
=

X
f ∈F
v∈UV
X
δ(f ) − 4 + 8 +
δ(v) − 4
v∈UV
= 2|E| − 4|F | + 8 + 2|E| − 4|V |
EF
= 4 |E| − |F | − |V | + 2 = 0.
Aus Formel (5.1) folgt, dass der Fluss über die Kanten (s, uv ), (s, uf ) sowie
(uf , t) gleich der Kapazität der Kanten ist. Der Fluss in einen Knoten uv ∈
UV ist ≤ 3, da uv nur eine eingehende Kante (s, uv ) besitzt, deren Kapazität
≤ 3.
5.3. ORTHOGONALISIERUNG
45
1
uv2
2
3
uv3
u f3
u f2
s
uv6
t
2
u v1
uv4
1
uv5
1
u f1
(a)
uv2
uv3
u f3
u f2
s
u v1
uv6
uv4
1
t
uv5
9
u f1
(b)
uv3
uv2
u f2
s
uf3
uv4
uv1
uv6
t
uv5
uf1
(c)
uv2
uv3
u f2
s
uv1
u f3
uv4
uv6
t
u v5
u f1
(d)
Abbildung 5.5: Konstruktion des orthogonalen Netzwerks. Die gestrichelten
Kanten stellen die Kanten des zugrundeliegenden Graphs dar.
46
KAPITEL 5. DER TOPOLOGY-SHAPE-METRICS ANSATZ
Der Fluss im Netzwerk N (P ) kann nun wie folgt interpretiert werden: Jede Flusseinheit über eine Kante (uf , ug ) repräsentiert den Knick einer Kante,
die die beiden Faces f und g abgrenzt. Der Knick formt dabei einen 90 Grad
Winkel innerhalb des Face f und kann einer beliebigen abgrenzenden Kante
zugewiesen werden. Ein Fluss der Höhe x über eine Kante (uv , uf ) definiert
einen Winkel der Größe (x + 1) · 90 Grad zwischen den beiden Kanten von
P (f ), die zum Knoten v inzident sind. Ein Winkel von 90 Grad wird also
durch einen Fluss von 0 modelliert. Aus der Flusserhaltungsbedingung folgt,
dass die Summe der Winkel um einen Knoten v immer 360 Grad beträgt und
jedes Face f ein rektilineares Polygon bildet. Ein gültiger Fluss mit den Kosten b führt zu einer orthogonalen Repräsentation mit genau b Knicken. Ein
minimaler Kostenfluss führt also zu einer orthogonalen Repräsentation, die
eine minimale Anzahl von Kantenknicken besitzt. Ein detailierter Algorithmus zum Bestimmen der orthogonalen Repräsentation aus dem minimalen
Kostenfluss findet sich in [30].
Satz 3 Für einen planaren 4-Graphen G mit n Knoten und einer planaren
Repräsentation P , findet der vorgestellte Algorithmus eine knickminimale
orthogonale Repräsentation in der Zeit O(n2 log n).
Die Laufzeit wird dabei durch das Lösen des Min-Cost-Flow-Problems dominiert. Der Beweis des Satzes befindet sich in [30].
5.3.2
Das Kandinsky-Modell
Der im letzten Abschnitt vorgestellte Algorithmus kann nur für 4-Graphen
eingesetzt werden. Wenn der Grad eines Knotens größer als vier ist, würde
das im bisherigen Modell zu Überlappungen führen, da in einer orthogonalen
Gittereinbettung nur 4 verschiedene Richtungen an einem Knoten existieren und die Knoten als Punkte dargestellt wurden. Da Knoten, die UMLEntities repräsentieren, einen höheren Grad besitzen können, muss Tamassias Modell entsprechend erweitert werden. Eine solche Erweiterung bietet das
Kandinsky-Modell [18]. In ihm werden die Knoten als Rechtecke mit einheitlicher Größe dargestellt, deren Mittelpunkt auf einem Gitter liegt. Dieser
Abschnitt beschreibt die Erweiterung des orthogonalen Netzwerkes N (P )
zum quasi-orthogonalen Kandinsky-Netzwerk.
Um Knoten mit Grad > 4 zu modellieren, müssen 0 Grad Winkel zugelassen werden. Ein 0 Grad Winkel zwischen zwei Kanten würde, basierend
auf Tamassias Modell, durch einen Fluss von −1 von einem Knoten uv ∈ UV
zu einem Knoten uf ∈ UF modelliert werden. Die Größe des Winkels wäre
dann (1 + x) · 90 = 0 Grad. Im Kandinsky-Modell werden 0 Grad Winkel
durch einen Fluss von 1 in die entgegengesetzte Richtung, also von uf nach
uv , dargestellt. Dazu muss das Netzwerk N (P ) um folgende Kanten ergänzt
werden:
5.3. ORTHOGONALISIERUNG
47
• Kanten (uf , uv ) wobei gilt: uf ∈ UF , uv ∈ UV und es existiert bereits
eine Kante (uv , uf ) in N (P ). Die Kanten haben die Kosten 0 und die
Kapazität 1.
• Kanten (uv , t) wobei gilt: uv ∈ UV und δ(v) ≥ 5. Die Kanten haben
die Kosten 0 und die Kapazität δ(v) − 4.
Die Kanten (uv , t) sind nötig, da bei 0 Grad Winkeln zusätzlicher Fluss über
Kanten (uf , uv ) in den Knoten uv fließt, der dann auch wieder abfließen
können muss. Für Knoten uv mit δ(v) ≥ 5 existiert dann keine Kante (s, uv ).
Diese Erweiterung stellt noch kein gültiges Modell dar. Die weiteren Modifikationen basieren auf folgender Beobachtung: Wenn man von Mehrfachkanten absieht, verbindet jede Kante, die von der selben Knotenseite ausgeht, verschiedene Nachbarknoten. Da die Knoten zentriert auf einem Gitter
angeordnet werden, können solche Kanten nicht vollständig parallel verlaufen, ohne das Überlappungen entstehen. Es kann also maximal eine Kante geben, die geradlinig verläuft, die anderen Kanten müssen knicken. Im
Kandinsky-Modell erzeugt deshalb jeder 0 Grad Winkel einen Knick einer
der beiden beteiligten Kanten. Solche Knicke werden Kandinsky-Knicke genannt, die herkömmlichen Knicke nennt man Face-Knicke. Die Kante ohne
Kandinsky-Knick wird als Mittelkante bezeichnet, obgleich sie nicht immer
die mittlere Kante im topologischen Sinne darstellen muss. Für alle Kanten, die sich an derselben Knotenseite befinden, gilt folgendes: Alle Kanten,
die bezüglich der zyklischen Kantenordnung links von der Mittelkante liegen, müssen nach links knicken. Kanten, die sich rechts von der Mittelkante
befinden, müssen entsprechend nach rechts knicken. Ein Kandinsky-Knick
wird also nicht durch die Topologie der Graphstruktur, sondern durch diese
Eigenschaft des Modells verursacht. Eine weitere wichtige Eigenschaft des
Kandinsky-Modells ist, dass es keine leeren Faces erlaubt, d.h. keine Dreiecke, die eine leere Region beschreiben (vgl. Abb. 5.6). Diese Eigenschaft
Abbildung 5.6: Zwei Möglichkeiten für leere Faces, welche im verwendeten
Kandinsky-Modell nicht erlaubt sind.
führt zu folgendem Lemma:
Lemma 1 Jedem 0 Grad Winkel einer Kandinsky-Zeichnung kann eindeutig
ein 270 Grad Winkel zugeordnet werden.
48
KAPITEL 5. DER TOPOLOGY-SHAPE-METRICS ANSATZ
Der Beweis dazu befindet sich in [18]. Diese Eigenschaft ist erforderlich,
damit der minimale Kostenfluss in eine gültige quasi-orthogonale Repräsentation umgewandelt werden kann.
Die Beobachtungen können nun wie folgt umgesetzt werden: Sei v ein
Knoten von G und e1 , e2 zwei benachbarte Kanten, die zu v inzident sind.
Sei f das von e1 und e2 eingeschlossene Face, g das Face, dass durch die
Kante e1 vom Face f abgegrenzt wird und h das Face, dass durch die Kante
e2 vom Face f abgegrenzt wird (vgl. Abb. 5.7). Für die Realisierung eines 0
e1
e2
e1
uf
uf
ug
e2
uh
ug
uh
uv
uv
(a)
(b)
Abbildung 5.7: In beiden Abbildungen ist ein Fluss über beide Netzwerkkanten gleichzeitig verboten.
Grad Winkels zwischen den Kanten e1 und e2 muss eine Flusseinheit von uf
in den Knoten uv fließen. Dies ist jedoch nur dann zulässig, falls auch Fluss
von ug bzw. uh nach uf fließt, der dann den Kandinsky-Knick der Kante
e1 bzw. e2 formt. Deswegen modelliert man 0 Grad Winkel direkt durch
Kanten (ug , uv ) und (uh , uv ), welche Kosten 1 und Kapazität 1 besitzen.
Zur Berechnung der quasi-orthogonalen Repräsentation werden die Kanten
dann wieder durch die Originalkanten (ug , uf ) und (uf , uv ) bzw. (uh , uf )
und (uf , uv ) ersetzt. Bei dieser Modellierung entspricht nicht jeder gültige
Flusswert des Netzwerks einer gültigen Zeichnung. Um dies zu erreichen,
müssen folgende Eigenschaften gewährleistet werden:
• Da keine negativen Winkel existieren, darf nur entweder Fluss von ug
nach uv über e1 oder von uh nach uv über e2 fließen (vgl. Abb. 5.7(a))
(Fluss von eins in den Knoten bedeutet 0 Grad Winkel, Fluss von zwei
nicht definiert!).
• Falls eine Flusseinheit von ug nach uv über e1 fließt, darf nicht gleichzeitig eine Flusseinheit von uf nach uv über e1 fließen (vgl. Abb. 5.7(b)).
Dadurch wird gewährleistet, dass alle Kanten links von der Mittelkante nach links und alle Kanten rechts von der Mittelkante nach rechts
knicken.
5.3. ORTHOGONALISIERUNG
49
Um beide Eigenschaften gleichzeitig zu realisieren, wird das Netzwerk N (P )
wie folgt modifiziert: Für jede Kante ei eines Knotens v werden zwei Knoten
v,r
Hev,l
i und Hei erzeugt und für jedes Face f , das an den Knoten v angrenzt, ein
v
Knoten Hf . Nun müssen folgende Kanten zum Netzwerk N (P ) hinzugefügt
werden (vgl. Abb. 5.8):
v,l
• Kanten (uf , Hev,r
i ) und (uf , Hej ), wobei f das Face bezeichnet, das
durch die Kanten ei und ej begrenzt wird und ej die Kante, die bezüglich f in Richtung des Knotens v durchlaufen wird. Diese Kanten
besitzen die Kapazität 1 und die Kosten 2c + 1.
• Kanten (Hfv , uv ) mit der Kapazität 1 und den Kosten 0. Diese Kante
sorgt für die erste Eigenschaft, indem sie die Kapazität auf 1 beschränkt
und somit höchstens eine Flusseinheit in den Knoten fließen kann.
v,r
v
v
• Kanten (Hev,l
i , Hf ) und (Hej , Hf ), wobei für f und ej dasselbe gilt wie
oben. Diese Kanten besitzen die Kapazität 1 und die Kosten 0.
v,r
v,l
v,l
• Kanten (Hev,r
i , Hei ) und (Hei , Hei ) mit der Kapazität 1 und den Kosten −c. Jedes dieser Kantenpaare bildet einen Zykel mit den Kosten
−2c. Ein Pfad vom Knoten uf zum Knoten uv hat deshalb die Kosten
2c + 1 − 2c = 1. Wenn der Zykel schon gesättigt ist, besitzt der Pfad
die Kosten 2c + 1. Dadurch wird die zweite Eigenschaft erfüllt.
e1
H
e1
2c+1
uh
h
H
f
v
e2
H
v,r
e3
e3
H
v,r
e1
−c
2c+1
v
h
H
uf
v
f
uv
2c+1
g
e3
v,l −c
e1
2c+1
−c
−c v,l
H
e3
2c+1
v
H
g
ug
−c
2c+1
v,r
H
e2
H
−c
v,l
e2
e2
Abbildung 5.8: Das Kandinsky-Netzwerk um einen Knoten v. Die Kanten
ohne Kostenangaben haben die Kosten 0.
Durch die beschriebenen Änderungen entstehen Zyklen mit negativen
Kosten in N (P ). Dies schränkt die Möglichkeit der verwendeten Algorithmen
50
KAPITEL 5. DER TOPOLOGY-SHAPE-METRICS ANSATZ
zum Lösen des Min-Cost-Flow-Problems ein. Das entstandene Problem kann
durch ein Lineares Programm (ILP) formuliert werden, welches eine optimale
Lösung findet. Es ist aber kein Algorithmus bekannt, der das Problem in
polynomieller Zeit lösen kann. Deswegen wird eine Heuristik zum Lösen des
Problems verwendet. Die Heuristik basiert auf einem Algorithmus, der den
Fluss entlang billigster Wege von s nach t erweitert. Da die Zyklen und deren
Länge bekannt ist, kann man die billigsten Wege mit einer modifizierten
Version des Algorithmus von Dijkstra bestimmen. Durch die Heuristik kann
das Problem weiterhin in der Laufzeit O(n2 log n) gelöst werden, wobei die
gefundene Lösung aber nicht immer optimal ist.
Da UML-Klassendiagramme Knoten unterschiedlicher Größe enthalten,
muss das verwendete Modell mit diesen umgehen können. Das hier beschriebene Kandinsky-Modell bringt die dazu nötigen Eigenschaften schon mit.
Die Handhabung von Knoten unterschiedlicher Größe ist deshalb nur noch
ein Kompaktierungsproblem.
5.4
Kompaktierung
Um aus der orthogonalen Repräsentation H, die in der 2. Phase berechnet
wurde, eine orthogonale Gittereinbettung zu erhalten, müssen noch die Längen der horizontalen und vertikalen Kantensegmente berechnet werden. Bei
der Längenberechnung müssen folgende Punkte beachtet werden [30]:
• Die Längen aller Segmente sind positiv und ganzzahlig.
• Jeder Zykel des Graphen wird auf ein geradliniges Polygon abgebildet.
• Es existieren keine Segmente die sich schneiden, außer gegebenenfalls
an ihren gemeinsamen Endpunkten.
Der Kompaktierungsalgorithmus geht im Falle von 4-Graphen folgendermaßen vor: Zuerst wird eine normalisierte orthogonale Repräsentation H 0 erzeugt, indem jedes Face von H durch Hinzufügen von zusätzlichen Knoten
und Kanten in Rechtecke zerlegt wird. Um eine orthogonale Gittereinbettung Q0 zu erhalten, muss den Seiten der Rechtecke von H 0 eine konsistente,
ganzzahlige Länge zugewiesen werden. Danach werden die zusätzlich hinzugefügten Knoten und Kanten wieder aus Q0 entfernt, wodurch die orthogonale Gittereinbettung Q entsteht. Die Laufzeit dieser Vorgehensweise beträgt
O(|V | + |B|), wobei B die Menge der Knicke bezeichnet.
Der hier verwendete Kompaktierungsalgorithmus muss außerdem folgende zusätzliche Eigenschaften besitzen:
• Die Kompaktierung muss auch mit Graphen zurecht kommen, deren
maximaler Knotengrad größer als 4 ist, da Knoten in UML-Klassendiagrammen einen höheren Grad besitzen können.
5.4. KOMPAKTIERUNG
51
• Die Kompaktierung muss Knoten variabler Größe berücksichtigen, da
die Größe der Klassenknoten in UML-Klassendiagrammen von der Anzahl und Länge der Attribut- und Methodensignaturen abhängt und
somit variabel ist.
In [18] wird beschrieben, wie die Kompaktierung im Kandinsky-Modell
mit einheitlicher Knotengröße durchgeführt werden kann. Dabei werden die
Originalknoten durch Rechtecke aus mehreren „kleinen“ Knoten ersetzt (vgl.
Abb. 5.9). Dadurch entsteht ein planarer 4-Graph, der mit einer Variante
des vorherigen Algorithmus berechnet werden kann. Wählt man die Anzahl
der „kleinen“ Knoten pro Seite hoch genug, dann kann jede Mittelkante in
der Mitte der jeweiligen Knotenseite gezeichnet werden.
v
Abbildung 5.9: Ersetzung eines Knotens durch viele kleine Knoten.
Bei einer einheitlichen Knotengröße können die Knoten bei der Kompaktierung als Punkte angesehen werden. Es müssen also nur die Längen der
Kantensegmente berechnet werden, ohne Berücksichtigung der Knotengröße. Die Knoten können sich niemals überlappen. Besitzen die Knoten unterschiedliche Größen, wird die Kompaktierung komplizierter, da man jetzt
auch die Größe der Knoten während der Kompaktierung beachten muss. Die
entstehende Zeichnung soll dabei auch weiterhin keine Überlappungen zwischen Knoten besitzen.
Bei der Kompaktierung für das Kandinsky-Modell mit unterschiedlichen
Knotengrößen, wird zusätzlich eine Längenfunktion eingeführt. Das Kompaktierungsproblem kann dann durch ein lineares Programm (kandinsky linear program[15]) formuliert werden. Durch die Rechteckzerlegung wird gewährleistet, dass eine gültige Lösung für das lineare Programm gefunden
werden kann. Unter der Annahme, dass sich die Anzahl der Knicke linear
zur Anzahl der Knoten verhält, besitzt diese Vorgehensweise eine Laufzeit
von O(|V |). Genaueres dazu findet sich in [15].
Da in UML-Klassendiagrammen auch Beziehungen beschriftet werden
können, besteht ein weiteres Problem darin, diese Beschriftungen (labels)
geeignet zu platzieren. Die Beschriftung der Kanten (Labeling) erfolgt bei
vielen Algorithmen in einem extra Schritt im nachhinein. Um bessere Resul-
52
KAPITEL 5. DER TOPOLOGY-SHAPE-METRICS ANSATZ
tate zu erzielen, können die Beschriftungen jedoch bereits, wie in [22] und
[2] beschrieben, in der Kompaktierungsphase berücksichtigt werden.
Kapitel 6
Ein Layoutalgorithmus für
UML-Klassendiagramme
Im vorherigen Kapitel wurden existierende Algorithmen vorgestellt, die die
drei Phasen des Topology-Shape-Metrics Ansatzes für allgemeine Graphen
realisieren. In diesem Kapitel werden die Erweiterungen und Modifikationen
dieser Algorithmen vorgestellt, um die ermittelten Ästhetikkriterien, die sich
durch die Semantik von UML-Klassendiagrammen ergeben, in den Layoutalgorithmus mit einzubeziehen. Dazu gehören vor allem das Aufwärtszeichnen von Kanten sowie die Darstellung der Vererbungshierarchie durch Vererbungsgabeln. Der UML-Standard selbst macht keine Vorgaben zum Layout
von Klassendiagrammen.
Wie in Kapitel 3.5 ermittelt wurde, sind Graphen Guml = (Vuml , Euml ),
die UML-Klassendiagramme repräsentieren, teilgerichtete Graphen, die Mehrfachkanten und Selbstschleifen enthalten können. Die Knoten haben unterschiedliche Größen und ihr Grad kann größer als vier sein. Die Knotenmenge Vuml setzt sich aus folgenden disjunkten Knotenmengen zusammen: Der
Knotenmenge K, deren Elemente Klassen repräsentieren, der Knotenmenge S, deren Elemente Schnittstellen repräsentieren und der Knotenmenge
P , deren Elemente Pakete repräsentieren. Es gilt also: Vuml = K ∪ S ∪ P .
Die Kantenmenge Euml = Euml,D ∪ Euml,U besteht aus folgenden disjunkten
Kantenmengen:
Vererbungskanten:
EKVer ⊆ K × K, EKV er ⊆ Euml,D
ESVer ⊆ S × S, ESV er ⊆ Euml,D
EImpl ⊆ K × S, EImpl ⊆ Euml,D
Assoziationen:
EAss ⊆ V × V , EAss ⊆ Euml
Abhängigkeiten:
EAbh ⊆ V × V , EAbh ⊆ Euml,D
54
KAPITEL 6. EIN LAYOUTALGORITHMUS FÜR
UML-KLASSENDIAGRAMME
Es gilt also: Euml = EKVer ∪ESVer ∪EImpl ∪EAss ∪EAbh . Die Graphelemente
sind außerdem entsprechend der UML-Konvention beschriftet.
Der Eingabegraph G = (V, E) des Layoutalgorithmus unterscheidet folgende besondere Kantenmengen:
• E↑ ⊆ E, die Menge der gerichteten Kanten, die aufwärtsgezeichnet werden sollen. Der von E↑ induzierte Subgraph von G muss azyklisch sein.
Da in UML-Klassendiagrammen Beziehungen existieren, die durch gerichtete Kanten Euml,D dargestellt, aber dennoch nicht aufwärtsgerichtet gezeichnet werden (z.B. Assoziationen), unterscheidet man hier
diese beiden Kantenmengen. Die Kanten e ∈ Euml,D \E↑ sind bezüglich
des Graphen G ungerichtet.
• EHyp ⊆ E↑ , die Menge der Kanten, die Hyperkanten bilden sollen. All
diese Kanten sind aufwärtsgerichtet. Das Konzept der Hyperkanten,
das im nächsten Abschnitt vorgestellt wird, benötigt man, um Vererbungsgabeln zu realisieren.
• ETree ⊆ E↑ , eine Menge von Baumkanten. UML-Klassendiagramme
enthalten oft Baumhierarchien, welche auf diese Kantenmenge abgebildet werden können. Enthält die Menge ETree mehrere Bäume, dürfen
sich diese nicht überlappen, d.h. jeder Knoten ist höchstens Knoten eines Baumes. Damit die Baumhierarchie übersichtlich dargestellt werden kann, müssen die Baumkanten möglichst überkreuzungsfrei und
ohne zusätzliche Knicke gezeichnet werden. Die Minimierung der Anzahl der Kreuzungen und Knicke ist zwar ein allgemeines Kriterium,
Baumkanten besitzen diesbezüglich aber eine erhöhte Priorität gegenüber den anderen Kanten. Für das kreuzungsminimale bzw. knickminimale Zeichnen eines Baumes werden deswegen auch zusätzliche Kreuzungen bzw. Knicke der anderen Kanten in Kauf genommen. Eine übersichtliche Baumhierarchie fordert außerdem, dass die Kanten aufwärtsgerichtet gezeichnet werden. Deshalb gilt ETree ⊆ E↑ . Die Kanten zeigen dabei alle in Richtung der Wurzel r, für die somit δout,ETree (r) = 0
gilt.
Neben diesen Kantenmengen enthält der Eingabegraph außerdem noch Informationen über die Größe der Knoten sowie über die Beschriftungen der
Elemente. Da für diese Informationen keine Veränderungen an den bestehenden Algorithmen vorgenommen werden, müssen sie hier nicht weiter beachtet
werden.
Beim Layouten eines Graphen Guml werden dessen Kantenmengen, je
nach Bedarf, den Kantenmengen E↑ , ETree und EHyp zugeordnet. Dabei
muss lediglich darauf geachtet werden, dass die Zuordnung verträglich ist.
Durch die flexible Zuordnung können verschiedene Ästhetikpräferenzen berücksichtigt werden. Unter der Annahme, dass keine Mehrfachvererbung von
Klassen zugelassen wird, kann z.B. folgende Zuordnung gewählt werden:
6.1. HYPERKANTEN UND VERERBUNGSGABELN
55
E↑ = EKVer ∪ ESVer ∪ EImpl
EHyp = EKVer
ETree = EKVer
Durch diese Festlegung werden Vererbungs- und Implementierungsbeziehungen hierarchisch (aufwärtsgerichtet) dargestellt. Die Klassenvererbung soll
besonders hervorgehoben und durch Vererbungsgabeln (Hyperkanten) dargestellt werden.
6.1
Hyperkanten und Vererbungsgabeln
In UML-Klassendiagrammen erfreut sich die Verwendung von Vererbungsgabeln zur Darstellung der Vererbungshierarchie großer Beliebtheit. In einem
Graph entspricht diese Struktur einer Hyperkante zwischen dem Knoten,
der die Superklasse repräsentiert und den Knoten, die die Subklassen repräsentieren (vgl. Abb. 6.1(b)). Eine Hyperkante ist eine Kante, die mehr als
zwei Knoten verbindet. Ein Graph der Hyperkanten enthält, nennt man Hypergraph. Um weiterhin mit normalen Graphen arbeiten zu können, werden
Hyperkanten durch das Verwenden eines Hilfsknotens modelliert, in dem sich
alle beteiligten Kanten treffen (vgl. Abb. 6.1(c)).
v
u1
u2
(a)
v
u3
u1
u2
v
u3
u1
(b)
u2
u3
(c)
Abbildung 6.1: Ersetzung von Hyperkanten.
Im folgenden wird beschrieben, wie das Konzept angewendet werden
kann, um aus der einfachen Darstellung die Abb. 6.1(a) zeigt, die gewünschte Vererbungsstruktur zu erzeugen. Sei v ein Knoten, der eine Superklasse
repräsentiert, und USub,v die Menge der Knoten, die eine Subklasse von v repräsentieren. Für jeden Knoten u ∈ USub,v existiert demnach eine gerichtete
Kante e = (u, v). Für diese Kanten soll gelten e ∈ EHyp . Um eine Hyperkante zu modellieren, wird nun für jede Superklasse v des Graphen, die mehr
als eine Subklasse besitzt, ein Hilfsknoten vDummy erzeugt und durch eine
gerichtete Kante (vDummy , v) mit dem Superklassenknoten verbunden. Jede
56
KAPITEL 6. EIN LAYOUTALGORITHMUS FÜR
UML-KLASSENDIAGRAMME
Kante (u, v) mit u ∈ USub,v wird aus dem Graphen entfernt und durch die
Kante (u, vDummy ) ersetzt (vgl. Abb. 6.1(c)). Damit die Struktur einer Vererbungsgabel entsteht, muss den Kanten außerdem eine entsprechende Form
zugewiesen werden (vgl. Abb.4.1(c)). Der nächste Abschnitt zeigt, wie man
die Form von Kanten festlegen kann. In Abschnitt 6.3.2 wird beschrieben,
wie man eine einheitliche Höhe der Geschwisterknoten erreichen kann. Damit sich die Kanten (u, vDummy ) in der Horizontalen überlappen, wird dem
Hilfsknoten vDummy einfach eine entsprechend kleine Größe zugewiesen.
Bei der vorgestellten Transformation muss folgendes beachtet werden:
Die erzeugten Kanten gehören denselben Kantenmengen wie die Originalkanten an, d.h. sind die Originalkanten aufwärtsgerichtet, dann auch die
neuen Kanten. Dasselbe gilt auch für die Kantenmengen EHyp und ETree .
Durch die beschriebene Transformation wird eine vorliegende Baumeigenschaft nicht zerstört.
Die Zeichnung eines Graphen sollte keine zusätzlichen Knoten oder Kanten enthalten. Deshalb müssen die Hilfsknoten und die hinzugefügten Kanten
nach dem Layouten wieder entfernt und die Originalkanten entsprechend
wieder eingefügt werden. Das Layout einer Originalkante (u, vSuper ) setzt
sich aus dem Layout der Kante (u, vDummy ) und der Kante (vDummy , v)
zusammen. Alle Originalkanten überdecken sich also bezüglich des Kantenabschnitts (vDummy , v), so dass der Hyperkanteneffekt entsteht.
Die Laufzeit für die Hyperkanten-Transformation setzt sich folgendermaßen zusammen: Man geht für alle Knoten die inzidenten Kanten durch. Trifft
man dabei auf eingehende Kanten e ∈ EHyp , erzeugt man einen Hilfsknoten
und führt die vorgestellte Transformation durch. Die Laufzeit beträgt also
O(|V | + |E|). Beim Entfernen der Hilfsknoten müssen die Kanten wieder
entsprechend ersetzt werden. Auch das geht in Linearzeit.
Wenn man das Hyperkanten-Konzept nicht nur in Baumhierarchien verwenden will, ergeben sich folgende Erweiterungsmöglichkeiten:
• Bis jetzt wurden immer nur eingehende, aufwärtsgerichtete Kanten zu
einer Hyperkantenstruktur zusammengefasst. Man kann aber analog
auch alle ausgehenden, aufwärtsgerichteten Kanten zusammenfassen
(vgl. Abb. 6.2(a)).
• Man kann Kanten in verschiedene Gruppen einteilen und dann jeweils
die Kanten eines Knotens, die derselben Gruppe angehören, durch eine
Hyperkantenstruktur zusammenfassen (vgl. Abb. 6.2(b)). Erfolgt die
Gruppierung über die Kantenart, können Baumkanten und gewöhnliche aufwärtsgerichtete Kanten an einem Knoten separat zusammengefasst werden. Der Eingabegraph kann auch entsprechende Markierungen für die Gruppen erhalten.
6.2. DER BASISALGORITHMUS
v1
v2
u
57
v3
v
u1
(a)
u2
w1
w2
(b)
Abbildung 6.2: Mögliche Erweiterungen des Hyperkantenkonzepts.
6.2
Der Basisalgorithmus
In diesem Abschnitt wird der Basisalgorithmus vorgestellt, der die Gabelform der Vererbungskanten sowie die Aufwärtsrichtung der Kanten aus E↑
realisiert. Im folgenden wird von einer aufwärtsplanaren Einbettung des von
der Kantenmenge E↑ induzierten Subgraphen ausgegangen.
Da Graphen, die UML-Klassendiagramme repräsentieren, eine variable
Knotengröße und Knoten v mit δ(v) > 4 besitzen, bietet sich für die Orthogonalisierung das Kandinsky-Modell an. Die Orthogonalisierung wird in
zwei Phasen aufgeteilt. Die erste Phase legt die Form der aufwärtsgerichteten
Kanten fest. In der zweiten Phase wird die Form der ungerichteten Kanten so
bestimmt, dass die Form, die den aufwärtsgerichteten Kanten in der ersten
Phase zugewiesen wurde, beibehalten werden kann.
Zunächst wird ein Algorithmus vorgestellt, der die Form der aufwärtsgerichteten Kanten festlegt, gefolgt von einem Algorithmus zur Knickreduzierung. Anschließend erfolgt eine Beschreibung der nötigen Änderungen, um
die vorgegebenen Kantenformen im Kandinsky-Netzwerk zu berücksichtigen.
Schließlich wird das Problem der einheitlichen Ausrichtung der aufwärtsgerichteten Kanten gelöst.
6.2.1
Formzuweisung für die aufwärtsgerichteten Kanten
Zu Beginn des Kapitels wurden die Beziehungskanten Euml den Kantenmengen E↑ , ETree und EHyp zugeordnet. Das Ziel dieser Zuordnung ist, dass die
entsprechenden Kanten eine bestimmte Form erhalten, so dass übersichtliche Klassendiagramme entstehen. Den Kanten der Kantenmenge E↑ muss
eine Form zugewiesen werden, die eine einheitliche Kantenrichtung gewährleistet. Die Kanten der Kantenmenge EHyp sollen zusätzlich eine Gabelform
erhalten. Dabei ist zu beachten, dass durch Kreuzungen geteilte Kanten mit
mehreren Kanten in diesen Kantenmengen vertreten sein können.
58
KAPITEL 6. EIN LAYOUTALGORITHMUS FÜR
UML-KLASSENDIAGRAMME
Im folgenden wird ein Algorithmus vorgestellt [16], der den aufwärtsgerichteten Kanten eine Form zuweist, die verträglich mit dem KandinskyModell ist und einen monoton steigenden Verlauf der aufwärtsgerichteten
Kanten garantiert. Der Algorithmus arbeitet dazu auf den durch die Kantenmenge E↑ induzierten Subgraphen G↑ = (V↑ , E↑ ). Dabei wird angenommen,
dass G↑ zusammenhängend ist. Wie dies gewährleistet werden kann wird in
Abschnitt 6.2.4 erläutert. Die Form einer Kante wird durch eine Zeichenkette beschrieben, die aus Elementen der Menge {←, ↑ , →} besteht. Da
die Kanten aufwärtsgerichtet sind und somit monoton steigend gezeichnet
werden sollen, darf die Richtung ↓ nicht vorkommen. Jedes Element der Zeichenkette gibt die Richtung des zugehörigen Kantensegmentes an. Zwischen
zwei aufeinanderfolgenden Elementen der Zeichenkette besteht also immer
ein Knick. Zwei aufeinanderfolgende Richtungsangaben müssen konsistent
sein, d.h. die Folge ←, → bzw. →, ← ist nicht erlaubt.
Der Algorithmus bestimmt die Form einer Kante (v, w) ∈ E↑ in zwei
Schritten. Am Knoten v bekommt die Kante ihre Fußform und am Knoten
w ihre Kopfform zugewiesen. Durch diese separate Zuweisung ist es möglich,
alle Knoten aus V↑ der Reihenfolge nach durchzugehen und den inzidenten,
aufwärtsgerichteten Kanten die entsprechende Fuß- bzw. Kopfform zuzuweisen. Die beiden Formen werden dabei entsprechend miteinander verknüpft.
Die Fußform steht dabei immer am Anfang der Zeichenkette. Da jede Fußform mit einem ↑ endet, ist eine konsistente Verknüpfung gewährleistet.
Der Algorithmus setzt voraus, dass Kreuzungsknoten und HyperkantenHilfsknoten entsprechend markiert sind. An den verschiedenen Knotentypen
werden den inzidenten Kanten dann folgende Formen zugewiesen:
• Handelt es sich um einen normalen Knoten, dann gilt folgender Grundsatz: Alle eingehenden aufwärtsgerichteten Kanten befinden sich an der
Unterseite und alle ausgehenden aufwärtsgerichteten Kanten an der
Oberseite des Knotens.
Für die ausgehenden Kanten bestimmt man eine Mittelkante, die die
Fußform ↑ zugewiesen bekommt. Alle ausgehenden Kanten, die sich
links von der Mittelkante befinden, müssen nach links knicken und bekommen daher die Fußform ↑←↑ zugewiesen. Alle ausgehenden Kanten die sich rechts von der Mittelkante befinden, müssen nach rechts
knicken und bekommen daher die Fußform ↑→↑ zugewiesen. Die Mittelkante wählt man wie folgt: Existiert eine ausgehende Baumkante
(höchstens eine), dann wird diese als Mittelkante gewählt. Ansonsten
wird die Kante als Mittelkante gewählt, die sich bezüglich der zyklischen Kantenordnung der ausgehenden Kanten um den Knoten in der
Mitte befindet. Bei der Zuweisung der Kopfform der eingehenden Kanten geht man folgendermaßen vor: Zuerst wird wieder eine Mittelkante
gewählt. Die Kanten links von der Mittelkante bekommen die Kopfform
→↑ und die Kanten rechts von der Mittelkante die Kopfform ←↑ zu-
6.2. DER BASISALGORITHMUS
59
gewiesen. Wenn ein Knoten mehrere eingehende Baumkanten besitzt,
wählt man die Baumkante, die sich bezüglich der zyklischen Kantenordnung der eingehenden Baumkanten um den Knoten in der Mitte
befindet, als Mittelkante. Ansonsten wählt man die Mittelkante wie
bei den ausgehenden Kanten. Abb. 6.3(a) und Abb. 6.3(b) zeigen die
Formzuweisung an einem normalen Knoten. In Abb. 6.3(b) stellen die
dicken Kanten Baumkanten dar.
• Handelt es sich um einen Hyperkanten-Hilfsknoten, dann wird der ausgehenden Kante die Fußform ↑ zugewiesen. Ist die Anzahl der eingehenden Kanten gerade, dann wird der rechten Hälfte der eingehenden Kanten die Kopfform ← und der linken Hälfte die Kopfform → zugewiesen
(vgl. Abb. 6.3(c)). Ist die Anzahl der eingehenden Kanten ungerade,
so wird der mittleren eingehenden Kante keine Kopfform zugewiesen
(vgl. Abb. 6.3(d)). Besitzen die eingehenden Kanten die Fußform ↑,
dann stellt diese Formgebung eine Art Zentrierung der Kindknoten
dar, da die Anzahl der Knoten auf der rechten Seite der Anzahl der
Knoten auf der linken Seite entspricht. Die Zentrierung bezieht sich
dabei jedoch nur auf die Anzahl der Knoten und nicht auf die Metrik.
• Handelt es sich um einen Kreuzungsknoten, gilt folgendes: Ein Kreuzungsknoten entsteht durch zwei sich kreuzende Kanten e und e0 . Sind
diese Kanten aufwärtsgerichtet, dann wird die Form der Kanten am
Kreuzungsknoten so festgelegt, dass die eine Kante gerade verläuft
und die andere knickt. Die gerade Kante wird dabei folgendermaßen
bestimmt: Ist die Kante e eine Baumkante, dann verläuft e gerade und
e0 knickt. Ansonsten ist e die knickende und e0 die gerade Kante. Durch
diese Zuordnung wird gewährleistet, dass Baumkanten an Kreuzungen
nur dann knicken, wenn sie sich mit einer anderen Baumkante kreuzen. Somit können Bäume immer möglichst ohne zusätzliche Knicke
dargestellt werden.
Sei e die gerade und e0 die knickende Kante. Durch den Kreuzungsknoten wird die Kante e in eine ausgehende eout und eine eingehende
Kante ein geteilt. Aus der Kante e0 entstehen analog die Kanten e0out
und e0in . Die Kante eout bekommt die Fußform ↑ zugewiesen. Die Form
der Kanten e0out und e0in ist abhängig von der zyklischen Ordnung der
Kanten um den Kreuzungsknoten. Entweder bekommt die Kante e0out
die Fußform →↑ und die Kante e0in die Kopfform → (vgl. Abb. 6.3(e))
oder die Kante e0out bekommt die Fußform ←↑ und die Kante e0in die
Kopfform ← zugewiesen (vgl. Abb. 6.3(f)). Ist nur eine der beiden an
der Kreuzung beteiligten Kanten aufwärtsgerichtet, dann wird diese
Kante gerade gezeichnet (vgl. Abb. 6.3(g)), die ungerichtete Kante bekommt keine Form.
KAPITEL 6. EIN LAYOUTALGORITHMUS FÜR
UML-KLASSENDIAGRAMME
60
v
v
h
h
(a)
(b)
(c)
(d)
c
c
(e)
(f)
c
(g)
Abbildung 6.3: Die vom Algorithmus zugewiesenen Kantenformen. Die
durchgängigen Kantensegmente haben ihre Form durch den Knoten erhalten.
Die dicken Kanten repräsentieren Baumkanten. Mit v werden die normalen
Knoten, mit h die Hyperkanten-Hilfsknoten und mit c die Kreuzungsknoten
bezeichnet.
Die durch den Algorithmus zugewiesene Form sorgt für einen monoton
steigenden Verlauf der aufwärtsgerichteten Kanten. Da G↑ aufwärtsplanar
eingebettet ist, führt die zugewiesene Form zu einer gültigen Zeichnung, denn
jeder aufwärtsplanare Graph besitzt nach [8] eine Aufwärtszeichnung, in der
die Knoten durch horizontale und die Kanten durch vertikale Linien repräsentiert werden können. Wenn man die horizontalen Linien durch die vom
Algorithmus zugewiesenen Kantenformen ersetzt, erhält man somit eine gültige Zeichnung.
Durch die beschriebene Formzuweisung des Algorithmus kann eine Kante
des eingebetteten Graphs höchstens vier Knicke besitzen. Die Anzahl der
erzeugten Knicke ist also O(|V | + c).
Der Algorithmus geht die Knoten von G↑ der Reihe nach durch und weist
den inzidenten Kanten eine entsprechende Form zu. Da der Graph planar ist,
geht das in der Laufzeit O(|V | + c).
6.2. DER BASISALGORITHMUS
6.2.2
61
Knickreduzierung
Der gerade vorgestellte Algorithmus erzeugt einige überflüssige Knicke, die
man nachträglich entfernen kann. Dazu werden die Zeichenketten, die die
Form der Kanten beschreiben, mit bestimmten Mustern verglichen. Entspricht eine Zeichenkette einem bestimmten Muster, dann kann sie durch
eine kürzere Zeichenkette ersetzt werden, wodurch die Anzahl der Knicke
der dazugehörigen Kante reduziert wird. Die erste und die letzte Richtung
einer Kante darf dabei nicht verändert werden, damit die Aufwärtsrichtung
erhalten bleibt. Tabelle 6.1 zeigt die Muster und die entsprechenden Vereinfachungen. Es werden nur Muster beachtet, die bei der Formgebung entstehen
können. Wie aus Tabelle 6.1 ersichtlich ist, spielt es für die Vereinfachung
Form
Bedingung
←↑←
v und w sind Kreuzungsknoten
→↑→
v und w sind Kreuzungsknoten
←↑←↑
v ist Kreuzungsknoten
→↑→↑
v ist Kreuzungsknoten
↑←↑←
w ist Kreuzungsknoten
↑→↑→
w ist Kreuzungsknoten
↑←↑←↑
↑→↑→↑
Tabelle 6.1: Vereinfachung der Form von Kanten
neue Form
←
→
←↑
→↑
↑←
↑→
↑←↑
↑→↑
e = (v, w).
der Kantenform eine Rolle, ob die Endpunkte der Kante Kreuzungsknoten
sind oder nicht. Das beruht auf der Eigenschaft der Kreuzungsknoten, dass
jede Knotenseite nur eine Kante besitzt. Abb. 6.4 zeigt ein Beispiel für eine
Knickreduzierung.
Auch nach Durchführung der Vereinfachungen aus Tabelle 6.1 können
noch unnötige Knicke vorhanden sein. Es treten z.B. Fälle auf, in denen
die Form ↑→↑ zwischen zwei gewöhnlichen Knoten vereinfacht werden kann
(vgl. Abb.6.5(a)). Häufig existieren aber auch Anordnungen, bei denen dies
nicht möglich ist (vgl. Abb.6.5(b)). Da es sehr komplex ist, für jeden Fall
zu überprüfen, ob eine geeignete Anordnung für eine Vereinfachung vorliegt,
werden hier nur Vereinfachungen durchgeführt, die immer angewendet werden können.
Bei den bisherigen Vereinfachungen genügt es, jeweils die Zeichenkette
einer Kante sowie den Typ der Endpunkte zu betrachten. An Kreuzungsknoten ergibt sich eine weitere Möglichkeit, die Anzahl der Knicke zu reduzieren.
Dazu muss die Form aller vier, zum Kreuzungsknoten inzidenten, Kanten betrachtet werden. Dies ist nur möglich, falls die Kanten aufwärtsgerichtet sind.
Wenn die ausgehende Kante an der Oberseite des Kreuzungsknotens keinen
KAPITEL 6. EIN LAYOUTALGORITHMUS FÜR
UML-KLASSENDIAGRAMME
62
2
4
1
3
5
6
2
4
1
3
(a)
5
6
(b)
Abbildung 6.4: Beispiel zur Knickreduzierung. Die linke Abbildung zeigt die
Form der Kanten vor der Knickreduzierung, die rechte Abbildung die Form
nach der Knickreduzierung.
3
4
2
1
(a)
3
4
2
1
(b)
Abbildung 6.5: In der linken Abbildung kann die Form der Kante (4, 3) auf
↑ reduziert werden. In der Anordnung der rechten Abbildung ist dies nicht
möglich.
Hyperkanten-Hilfsknoten als Endpunkt besitzt und die Vereinfachungen aus
Tabelle 6.1 noch nicht durchgeführt wurden, kann folgende Transformation
angewendet werden: Knicken alle Kanten vom Kreuzungsknoten aus gesehen
einheitlich nach links bzw. nach rechts, kann man jeweils die erste Richtungsangabe der Form der ausgehenden Kanten und die letzte Richtungsangabe
der Form der eingehenden Kanten aus den Zeichenketten entfernen (vgl.
Abb. 6.6).
Diese Transformation kann folgendermaßen interpretiert werden: Bei der
Formzuweisung an einem Kreuzungsknoten entscheidet man sich für eine
Kante, die gerade verlaufen soll, die andere knickt. Angenommen e ist die
knickende Kante. Hätte man sich bei der Formzuweisung entschieden, die
Kante e0 knicken zu lassen, dann entspräche die Form der Kreuzungskanten,
nachdem die in Tabelle 6.1 vorgestellten Vereinfachungen vorgenommen wurden, der Form der Kreuzungskanten, die durch die vorgestellte Transformation entstanden ist. Aus dieser Interpretation folgt, dass die Aufwärtsrichtung
6.2. DER BASISALGORITHMUS
e1
e4
e1
c
e3
63
e4
e2
c
e4
e3
c
e3
e3
e2
e1
e4
c
e2
e2
e1
Abbildung 6.6: Entfernen von Knicken bei Kreuzungsknoten.
der Kanten durch die Transformation nicht zerstört werden kann. Durch die
Transformation werden ungünstige Entscheidungen bei der Formgebung an
den Kreuzungsknoten korrigiert.
Es sind weitere Transformationen möglich, die auf diesem Prinzip basieren. Das nachträgliche Tauschen der knickenden Kante an einem Kreuzungsknoten ist allgemein nur dann sinnvoll, wenn nach der Transformation
Kanten durch die einfache Knickreduzierung vereinfacht werden können und
keine beabsichtigte Form zerstört wird. In Abb. 6.7(a) wäre eine Transformation unsinnig. Falls drei Kanten an einem Kreuzungsknoten in dieselbe
Richtung knicken, wie in Abb. 6.7(b), kann eine Transformation sinnvoll
sein. Wie zu sehen ist, bekommt hier eine Kante einen zusätzlichen Knick.
Die Anzahl der Knicke wird also nur um zwei reduziert.
e1
e4
e3
c
e1
e4
c
e3
e2
(a)
e1
e4
e2
e3
c
e1
e4
c
e2
e3
e2
(b)
Abbildung 6.7: Weitere Transformationen bei Kreuzungsknoten.
Für die Laufzeit der vorgestellten Knickreduzierung gilt folgendes: Man
läuft alle Kreuzungsknoten ab und schaut, ob die Kreuzung vereinfacht werden kann. Merkt man sich die Kreuzungsknoten in der Einbettungsphase,
kann das in O(c) erledigt werden. Danach geht man alle Kanten durch, vergleicht deren Form mit den Mustern und weist ihnen gegebenfalls eine neue
Form zu. Da der Graph planar ist, geht dies in O(|V | + c). Daraus resultiert
eine Gesamtlaufzeit von O(|V | + c).
KAPITEL 6. EIN LAYOUTALGORITHMUS FÜR
UML-KLASSENDIAGRAMME
64
6.2.3
Umsetzung der vorgegebenen Form durch das KandinskyNetzwerk
In diesem Abschnitt werden die Modifikationen am Kandinsky-Netzwerk vorgestellt, die notwendig sind, um Winkel zwischen Kanten sowie Kantenknicke
vorgeben zu können, die dann durch den Netzwerkfluss realisiert werden sollen. Anschließend wird beschrieben, wie die Form, die bei der Formzuweisung
ermittelt wurde, auf das Netzwerk transformiert werden kann. Unter Einbehaltung der vorgegebenen Form, muss dann die Form der ungerichteten
Kanten bestimmt werden. Der folgende Abschnitt basiert im wesentlichen
auf den in [3] beschriebenen Modifikationen.
Modifikation des Netzwerks
Um die Größe von Winkeln vorgeben zu können, müssen zusätzliche Knoten und Kanten in das Kandinsky-Netzwerk N (P ) aufgenommen werden.
Für jeden vorgegebenen Winkel zwischen zwei aufeinanderfolgenden Kanten e1 und e2 des Knotens v wird ein Winkelknoten ave1 ,e2 in das Netzwerk
eingefügt. Die Menge der Winkelknoten von v wird mit UA (v) bezeichnet.
Ein Knoten v wird im Netzwerk durch den Knoten uv repräsentiert. Für
jeden Knoten av ∈ UA (v) werden die Kanten (uv , av ) und (av , uv ) mit den
Kosten ca und unbeschränkter Kapazität in das Netzwerk eingefügt. Für
einen Winkelknoten ave1 ,e2 sei uf der Netzwerkknoten, der das Face f repräsentiert, welches von den beiden Kanten e1 und e2 begrenzt wird. Die
Kanten (uv , uf ) und (Hfv , uv ) müssen nun durch die Kanten (av , uf ) und
(Hfv , av ) ersetzt werden. Auf der Menge der Winkelknoten UA ist eine Funktion angle : UA → {−1, 0, 1, 2, 3} definiert, die die Größe des Winkels
vorgibt.
Ein Winkelknoten av soll für einen Winkel von 1 + angle(av ) · 90 Grad sorgen. Um die vorgegebenen Winkel umsetzen zu können, müssen zusätzlich
folgende Kanten in das Netzwerk N (P ) eingefügt werden:
• Kanten (s, av ) von der Quelle s zum Winkelknoten av ∈ UA (v), falls
angle(av ) > 0. Diese Kanten haben die Kosten 0 und die Kapazität
angle(av ).
• Kanten (av , t) vom Winkelknoten av ∈ UA (v) zur Senke t, falls
angle(av ) < 0. Diese Kanten haben die Kosten 0 und die Kapazität
−angle(av ).
Außerdem muss der Wert angle(av ) für jeden Winkelknoten av ∈ UA (v) vom
Fluss in den Knoten uv abgezogen werden. Für das Flussangebot (supply)
am Knoten uv gilt somit:
supply(uv ) = 4 − δ(v) −
X
av ∈UA (v)
angle(av ).
6.2. DER BASISALGORITHMUS
e1
uf
ug
v
Hf
uv
e1
e1
uh
v
Hh
65
(1, c b)
(1,0)
(2,0)
u b’ u b
v
Hg
ug
(a)
ug
(1, c b)
(1,0)
(1,2c)
uf
s
e2
w,l
He
e2
(2,0)
(2,0)
(2,0)
s
e3
uf
w,r
He
2
e2
w
(b)
(c)
2
Abbildung 6.8: Änderungen am Kandinsky-Netzwerks. Neu hinzugefügte
Knoten sind gelb gezeichnet, neu hinzugefügte Kanten haben eine transparente Pfeilspitze und veränderte Kanten sind gepunktet dargestellt.
Für die einzufügenden Kanten (s, uv ) und (uv , t) gilt nun: Falls supply(uv ) ≥
0, wird eine Kante (s, uv ) mit der Kapazität supply(v) und den Kosten
0 erzeugt. Falls supply(v) < 0, wird eine Kante (uv , t) mit der Kapazität
−supply(uv ) und den Kosten 0 erzeugt. Damit vorgegebene Winkel eingehalten werden können, muss die Größe der Winkel konsistent sein. Es können
beispielsweise keine zwei 270 Grad Winkel an einem Knoten entstehen. Falls
ein Winkel nicht eingehalten werden kann, entstehen Kosten von mindestens
ca , da mindestens eine Flusseinheit über eine Kante (uv , av ) oder (av , uv )
fließen muss.
Abb. 6.8(a) zeigt ein Beispiel für die beschriebene Modifikation. Zwischen den Kanten e1 und e2 sowie zwischen den Kanten e2 und e3 soll ein
vorgegebener Winkel realisiert werden. Dazu werden, wie beschrieben, zwei
Winkelknoten in N (P ) eingefügt und die entsprechenden Kanten erzeugt.
Die Winkelknoten sind gelb dargestellt, die neuen Kanten durch eine transparente Pfeilspitze und die geänderten Kanten durch eine gepunktete Linie.
Der Übersicht halber wurden die Kanten mit Endpunkt s oder t weggelassen.
Um neben Winkeln auch Knicke von Kanten vorgeben zu können, sind
folgende Modifikationen nötig: Für jeden Knick einer Kante e wird die Kante
durch einen Knickknoten b aufgeteilt, wodurch die Kanten e1 und e2 entstehen. Seien uf und ug die Netzwerkknoten, die die, von der Kante e getrennten, Faces f und g repräsentieren. Dann muss das Flussangebot an den
Knoten uf und ug zusätzlich um eine Einheit je Knickknoten verringert werden. Das Face g sei das Face, indem der Knick einen rechten Winkel bilden
66
KAPITEL 6. EIN LAYOUTALGORITHMUS FÜR
UML-KLASSENDIAGRAMME
soll. Für jeden Knickknoten b werden die Knoten ub und ub0 und folgende
Kanten in das Netzwerk N (P ) eingefügt (vgl. Abb. 6.8(b)):
• Eine Kante (s, ub ) von der Quelle s zum Knoten ub . Die Kante hat die
Kosten 0 und die Kapazität 2.
• Eine Kante (ub , uf ) vom Knoten ub zum Knoten uf . Die Kante hat die
Kosten 0 und die Kapazität 2.
• Eine Kante (ub0 , ug ) vom Knoten ub0 zum Knoten ug . Die Kante hat
die Kosten cb und die Kapazität 1.
• Eine Kante (ub , ub0 ) vom Knoten ub zum Knoten ub0 . Diese Kante hat
die Kosten 0 und die Kapazität 1. Der Zweck dieser Kante wird weiter
unten erläutert.
Zusätzlich erhalten die Kanten zwischen den Faces die Kosten cf > cb , damit
der Fluss, der vom Knoten ub in den Knoten uf fließt, nicht über die Kante
(uf , ug ) fließen kann.
Die Interpretation der Modifikation ist folgendermaßen: Der Knoten ub
muss einen Fluss der Höhe 2 auf seine ausgehenden Kanten verteilen. Dazu gibt es folgende Möglichkeiten: Entweder fließen beide Einheiten über
(ub , uf ) wodurch ein Winkel von 270 Grad zwischen den Kanten e1 und e2
im Face f entsteht, oder es fließt nur eine Flusseinheit über (ub , uf ) und eine
über die Kanten (ub , ub0 ) und (ub0 , ug ), wobei die Kosten cb entstehen und
der Knick nicht eingehalten wird.
Der erste und der letzte Knick einer Kante sind mögliche KandinskyKnicke. Diese werden speziell behandelt. In Abb. 6.8(c) stellt w einen gewöhnlichen Knoten dar, der über die Kante e2 mit dem Knickknoten b verbunden ist. Die Kante e2 kann am Knoten w einen Kandinsky-Knick erhalten. Deshalb wird eine extra Kante (ub0 , Hew,l
2 ), falls der gewünschte Knick
w,r
0
nach links gehen soll, bzw. (ub , He2 ), falls der Knick nach rechts gehen soll,
eingefügt. Diese Kante hat die Kosten 2c und die Kapazität 1. Durch sie
wird gewährleistet, dass der Kandinsky-Knick, der zu einem Knick in die
gewünschte Richtung führt, ohne Kosten realisiert werden kann. Denn, falls
der negative Zykel noch nicht gesättigt ist, sind die Kosten des KandinskyKnicks 2c − c − c = 0. Es besteht also die Möglichkeit, dass nur eine Einheit
über (ub , uf ) fließt, wodurch ein Winkel von 180 Grad zwischen den Kanten
e1 und e2 entsteht, aber der Knick dennoch durch den Kandinsky-Knick,
w,r
der durch Fluss über die Kante (ub0 , Hew,l
2 ) bzw. (ub0 , He2 ) verursacht wurde, eingehalten wird. Die Kante (ub , ub0 ) sorgt dafür, dass mindestens eine
Einheit in den Knoten uf fließt. Ansonsten würde eine inkonsistente Form
entstehen.
6.2. DER BASISALGORITHMUS
67
Transformation der vorgegebenen Form auf das Netzwerk
Die endgültige Form aller Kanten wird durch den Min-Cost-Flow des Netzwerks bestimmt. Damit die vorgegebene Form der aufwärtsgerichteten Kanten beibehalten wird, muss diese entsprechend durch das Netzwerk formuliert
werden. Um dies zu erreichen, geht man folgendermaßen vor: Für jeden Knick
einer Kante wird ein Knickknoten b in den Graphen eingefügt, der die Kante
aufteilt. Schließlich besitzen alle aufwärtsgerichteten Kanten nur noch eine
einfache Form. Nun wird das Kandinsky-Netzwerk erstellt, wobei für Knickknoten nur die Knoten und Kanten aus Abb. 6.8(b) erzeugt werden müssen. Ist der Knickknoten mit einem gewöhnlichen Knoten benachbart, wird
die zusätzliche Kante für mögliche Kandinsky-Knicke entsprechend eingefügt (vgl. Abb. 6.8(c)). Für je zwei aufeinanderfolgende aufwärtsgerichtete
Kanten eines gewöhnlichen Knotens, muss ein Winkelknoten und die dazugehörigen Kanten erzeugt werden. Die Größe des Winkels kann durch die
Form der betreffenden Kanten bestimmt werden. Liegen zwischen zwei aufwärtsgerichteten Kanten ungerichtete Kanten, dann werden diese, wie in
Abbildung 6.9 dargestellt, behandelt. Vom Flussangebot des Winkelknotens
muss dann außerdem die Anzahl der ungerichteten Kanten, die zwischen den
beiden aufwärtsgerichteten Kanten liegen, abgezogen werden.
e1
uh
uf
e3
ug
e2
Abbildung 6.9: Behandlung von ungerichteten Kanten bei der Abbildung auf
das Netzwerk. Die Kante e2 stellt eine ungerichtete Kante dar.
Aufwärtsgerichtete Kanten dürfen außer den vorgegebenen Knicken keine weiteren Knicke erhalten, da sonst die Aufwärtsrichtung zerstört werden
kann. Deshalb werden ihnen höhere Knickkosten zugewiesen. Um mit unterschiedlichen Knickkosten der Kanten arbeiten zu können, geht man folgendermaßen vor: Knicke, die keine Kandinsky-Knicke sind, werden durch Fluss
zwischen zwei Faces verursacht. Knicke können, wie in [30] beschrieben, einer
beliebigen Kante zugeordnet werden, die die beiden Faces abgrenzt. Bis jetzt
besitzen all diese Kanten die Kosten cf . Man legt nun eine Kostenfunktion
fest, die den Kanten abhängig vom Kantentyp unterschiedliche Kosten zu-
68
KAPITEL 6. EIN LAYOUTALGORITHMUS FÜR
UML-KLASSENDIAGRAMME
weist. Dabei sollte die billigste Kante mindestens cf Kosten. Eine mögliche
Zuordnung wäre z.B.:
M · cf falls e ∈ E↑ ,
cost(e) =
cf
sonst.
Die Kante (uf , ug ) zwischen den Faces f und g bekommt jetzt die Kosten
der billigsten Kante e zugewiesen, die die beiden Faces abgrenzt. Fließt Fluss
über (uf , ug ), dann können die Knicke alle der Kante e zugewiesen werden.
Neben den Kosten für Face-Knicke müssen auch die Kosten der KandinskyKnicke erhöht werden. Die Kosten für den Kandinsky-Knick einer Kante e
betragen 2c + cost(e). Wenn man M = ∞ wählt, ist gewährleistet, dass eine
aufwärtsgerichtete Kante niemals zusätzliche Knicke erhält.
Nachdem das Min-Cost-Flow-Problem gelöst wurde, kann die quasi-orthogonale Repräsentation bestimmt werden. Nun besitzen alle Kanten eine Form.
Die Knickknoten können jetzt wieder aus dem Graphen entfernt und durch
die ursprünglichen Kanten ersetzt werden. Die Form der ursprünglichen Kanten setzt sich dabei aus den Formen der entsprechenden Kantenteile zusammen.
Sei |E 0 | die Anzahl der Kanten des eingebetteten Graphen. Die Anzahl
der vorgegebenen Winkel ist ≤ |E 0 | und die Anzahl der vorgegebenen Knicke
ist ≤ 4|E 0 |. Da es sich um einen planaren Graphen handelt, kann die Transformation in O(|V | + c) stattfinden. Außerdem ist die Anzahl der Knoten im
Netzwerk weiterhin O(|V | + c). Das Lösen des
Netzwerkflussproblems kann
2
somit weiterhin in O (|V | + c) log(|V | + c) erfolgen.
6.2.4
Einheitliche Ausrichtung der aufwärtsgerichteten Kanten
Bei der Formzuweisung der aufwärtsgerichteten Kanten wurde angenommen,
dass der Subgraph G↑ zusammenhängend ist. Diese Annahme wird für die
einheitliche Ausrichtung der aufwärtsgerichteten Kanten benötigt. Die Ausrichtung der Kanten ist immer relativ zu den jeweiligen Endpunkten, d.h. an
einem Knoten zeigen alle aufwärtsgerichteten Kanten in dieselbe Richtung.
Sind zwei Knoten durch eine aufwärtsgerichtete Kante verbunden, garantiert die Formzuweisung, dass die Knoten dieselbe Ausrichtung besitzen. Die
aufwärtsgerichteten Kanten der beiden Knoten zeigen somit alle in dieselbe
Richtung. Induzieren die Kanten der Menge E↑ keinen zusammenhängenden
Subgraphen G↑ von G, dann sind die einzelnen Zusammenhangskomponenten von G↑ nicht gegeneinander ausgerichtet, da sie nur durch ungerichtete
Kanten verbunden sind. Deren Form wird nicht vorgegeben, sondern durch
den Netzwerkfluss bestimmt. Im folgenden wird ein Algorithmus vorgestellt,
der gewährleistet, dass der Subgraph G↑ zusammenhängend ist.
Handelt es sich bei dem Eingabegraph G um einen ungerichteten Graphen, d.h. E↑ = ∅, dann spielt die Ausrichtung der Kanten keine Rolle. An-
6.2. DER BASISALGORITHMUS
69
sonsten kann das Problem durch das Aufwärtsrichten ungerichteter Kanten
wie folgt gelöst werden:
• Zuerst wird auf den Kanten des Graphen G = (V, E) eine Kostenfunktion cost : E → {0, 1} definiert, wobei gilt:
0 falls e ∈ E↑ ,
cost(e) =
1 sonst.
• Nun wird ein Spannbaum TG = (V, E 0 ) von G ermittelt, der bezüglich
der Kostenfunktion cost minimale Kosten besitzt (vgl. Abb. 6.10(b)).
Der Spannbaum enthält also möglichst wenige ungerichtete Kanten.
• Sind alle Kanten des Spannbaumes aufwärtsgerichtet, ist die einheitliche Ausrichtung der Kanten gewährleistet, da G↑ dann zusammenhängend ist. Also müssen alle Kanten e = (v, w) für die gilt e ∈ E 0 und
e ∈
/ E↑ aufwärtsgerichtet werden. Es spielt dabei keine Rolle, ob die
dann aufwärtsgerichtete Kante von v nach w oder von w nach v zeigt,
da keine gerichteten Zyklen entstehen können (s. Satz 4). Nach dem
Aufwärtsrichten dieser Kanten ist die korrekte Ausrichtung gewährleistet und es gilt: E 0 ⊆ E↑ .
Satz 4 Sei TG = (V, E 0 ) ein Spannbaum von G mit minimalen Kosten bezüglich der Kostenfunktion cost. Durch das Aufwärtsrichten einer ungerichteten
Kante e ∈ E 0 können keine gerichteten Zyklen in G entstehen.
Beweis:
Angenommen durch das Aufwärtsrichten der ungerichteten Kante e = (v, w)
entsteht ein gerichteter Zyklus in G. Da ein Spannbaum per Definition keine
Zykel enthalten kann, müssen aufwärtsgerichtete Kanten e0 ∈ E↑ \ E 0 existieren, die an dem gerichteten Zyklus beteiligt sind. Wenn man die Kante
e aus dem Spannbaum entfernt, zerfällt dieser in zwei Komponenten Tv und
Tw , wobei v ∈ Tv und w ∈ Tw . Auf dem gerichteten Zykel existiert nun eine
Kante e0 = (v 0 , w0 ) ∈ E↑ \ E 0 , für die gilt: w0 ∈ Tv und v 0 ∈ Tw . Durch die
Hinzunahme dieser Kante entsteht ein Spannbaum, dessen Kosten um eine
Einheit geringer sind, als die Kosten von TG . Der Spannbaum TG besitzt also
keine minimalen Kosten, was ein Widerspruch zur Annahme darstellt.
Die folgende Beobachtung kann zur Verbesserung des Algorithmus verwendet werden: Nur Knoten mit aufwärtsgerichteten Kanten benötigen eine
einheitliche Ausrichtung. Es genügt also, wenn alle Kanten eines zusammenhängenden Subgraphs, der all diese Knoten enthält, aufwärtsgerichtet
werden. Der Algorithmus berechnet aber einen minimalen Spannbaum des
Graphen G. Ausgehend von dem minimalen Spannbaum kann der Subgraph
KAPITEL 6. EIN LAYOUTALGORITHMUS FÜR
UML-KLASSENDIAGRAMME
70
1
1
1
0
0
2
2
3
1
3
2
3
1
4
0
1
5
4
6
0
8
6
4
6
1
7
5
8
7
5
8
7
1
9
9
(a)
(b)
9
(c)
Abbildung 6.10: Bestimmung eines zusammenhängenden Subgraphs, der alle Knoten mit aufwärtsgerichteten Kanten enthält. Die markierten Kanten
sind ungerichtete Kanten, die aufwärtsgerichtet werden müssen. (a) zeigt
den Ausgangsgraph und die dazugehörigen Kantenkosten. (b) stellt den dazugehörigen minimalen Spannbaum dar und (c) den zusammenhängenden
Subgraph.
folgendermaßen ermittelt werden: Falls ein Blatt des Spannbaumes eine ungerichtete Kante besitzt, kann diese entfernt werden. Dadurch entstehen eventuell neue Blätter. Besitzt ein neues Blatt ebenfalls eine ungerichtete Kante,
kann auch diese entfernt werden. Der Vorgang wird solange wiederholt, bis
der Subgraph nur noch Blätter mit aufwärtsgerichteten Kanten besitzt. Aus
dem minimalen Spannbaum aus Abb. 6.10(b) entsteht so der Subgraph aus
Abb. 6.10(c). Algorithmus 1 berechnet den Subgraph.
Aus folgenden Gründen lohnt sich diese Verbesserung:
• Aufwärtsgerichtete Kanten verursachen oft zusätzliche Kreuzungen und
Knicke, deshalb sollte deren Zahl nicht unnötig erhöht werden.
• Da in UML-Klassendiagrammen häufig die Zahl der Assoziationsbeziehungen dominiert, existieren oft viele ungerichtete Kanten, die durch
diese Verbesserung nicht aufwärtsgerichtet werden müssen.
Die Gesamtlaufzeit setzt sich wie folgt zusammen: Die Zuweisung der
Kantengewichte geht in O(|E|). Da der Layoutalgorithmus für jede Zusammenhangskomponente eines Graphen ausgeführt wird, ist der Graph G zusammenhängend. Ein minimaler Spannbaum (minimum spanning tree) kann
6.3. VERBESSERUNGEN DES BASISALGORITHMUS
71
Algorithmus 1 : Verbesserung des Orientierungsalgorithmus.
Eingabe: TG = (V , E 0 ), ein minimaler Spannbaum von G
E↑ , die Menge der aufwärtsgerichteten Kanten
Ausgabe: Kantenmenge E 0 , die einen zusammenhängenden Subgraph von
G induziert, der alle Knoten mit aufwärtsgerichteten Kanten enthält
Leaves ← {v ∈ V : δE 0 (v) = 1}
while Leaves 6= ∅ do
v ← Element aus Leaves
e ← die zu v inzidente Kante
if e ∈
/ E↑ then
w ← der Nachbarknoten von v
E 0 ← E 0 \ {e}
if δE 0 (w) = 1 then
Leaves ← Leaves ∪ {w}
fi
fi
Leaves ← Leaves \ {v}
od
so mit Prim’s Algorithmus in O(|E| log |V |) berechnet werden. Das Aufwärtsrichten der ungerichteten Kanten kann in O(|E|) erledigt werden. Die
Laufzeit des Algorithmus 1 setzt sich wie folgt zusammen: Bestimmung der
Knoten mit Grad 1 geht in O(|V |). Ein Spannbaum besitzt |V | − 1 Kanten.
Jeder Knoten wird höchstens einmal in Leaves aufgenommen. Das Bestimmen, ob ein Knoten Grad 1 besitzt, geht in O(1). Also ergibt sich für die
Verbesserung eine Laufzeit von O(|V |) und somit eine Gesamtlaufzeit von
O(|E| log |V |).
6.3
Verbesserungen des Basisalgorithmus
Im vorherigen Abschnitt wurde der Basisalgorithmus vorgestellt. In diesem
Abschnitt werden Verbesserungen für den Basisalgorithmus erläutert.
6.3.1
Einbettung
Die Einbettung basiert auf der in Abschnitt 5.2 beschriebenen Vorgehensweise. Anstatt alle gerichteten Kanten aufwärtsplanar einzubetten, ist das
nur für Kanten aus E↑ nötig. Die im folgenden beschriebenen Erweiterungen
zielen darauf ab, die Kanten aus ETree möglichst schön darzustellen. Dazu
müssen folgende Punkte erfüllt werden:
KAPITEL 6. EIN LAYOUTALGORITHMUS FÜR
UML-KLASSENDIAGRAMME
72
1. Kreuzungen zwischen Baumkanten sollten möglichst vermieden werden, da der Baum sonst nicht zufriedenstellend dargestellt werden
kann.
2. Die Bäume sollten so eingebettet werden, dass sie möglichst wenig
Kreuzungen mit anderen Kanten besitzen.
Der erste Punkt kann durch eine Modifikation der GT-Heuristik realisiert
werden und der zweite Punkt durch unterschiedliche Gewichte beim Routen
der Kanten.
Änderung an der GT-Heuristik
Um zu verhindern, dass sich Baumkanten gegenseitig kreuzen, sollten sie
möglichst alle im initialen planaren Subgraphen enthalten sein. Beim nachträglichen Routen der Baumkanten über den Routinggraph kann die Überkreuzungsfreiheit nicht garantiert werden. Durch die hier vorgestellte Modifikation der ersten Phase der GT-Heuristik wird eine Knotenfolge erzeugt,
die zusammen mit einer geeigneten Kantengewichtung bei der Berechnung
der Maximum Independent Sets in der zweiten Phase, zu einem planaren
Subgraphen mit möglichst vielen Baumkanten führen soll. Dazu folgender
Satz:
Satz 5 Sei T = (V, E) ein Baum mit Wurzel r und Π die Knotenfolge,
die bei einer Tiefensuche von r aus entsteht. Dann gibt es keine Kantenpaare e1 , e2 ∈ E, die sich bezüglich der Knotenfolge Π schneiden (vgl. Abschnitt 5.2.1).
Beweis:
Angenommen es gibt eine Überschneidung zweier Kanten aus E, dann gibt
es Baumknoten a, b, c, d und Kanten e1 = (a, c), e2 = (b, d) für die gilt: e1
überkreuzt e2 (vgl. Abb. 6.11). Da b nach a und vor c steht und c Kind von
a
...
b
...
c
...
d
Abbildung 6.11: Zwei Kanten die sich bezüglich der Knotenfolge überschneiden.
a ist, muss b wegen der DFS-Ordnung ein Nachfolger von a sein. Da a direkt
mit c verbunden ist, kann c nicht Nachfolger von b sein. Da d in der Knotenfolge hinter c steht, kann d wegen der DFS-Ordnung kein Nachfolger von
b und somit auch kein Kind von b sein, was ein Widerspruch zur Annahme
darstellt.
6.3. VERBESSERUNGEN DES BASISALGORITHMUS
73
Da die aufwärtsgerichteten Kanten in UML-Graphen zur Wurzel zeigen, darf
ein Baumknoten v erst dann in die Knotenfolge aufgenommen werden, wenn
schon alle Kinder von v in der Knotenfolge enthalten sind. Wird die Knotenfolge, die bei einer Tiefensuche entsteht, umgedreht, ist diese Bedingung
erfüllt und Satz 5 immer noch anwendbar. Eine solche Knotenfolge führt
dazu, dass alle Kanten des Baumes in die Maximum Independent Sets aufgenommen werden können.
Unter der Annahme ETree = E↑ trifft nun folgendes zu: Enthält ETree
mehrere Bäume, dann kann die Knotenfolge durch Aneinanderketten der
Knotenfolgen der einzelnen Bäume erzeugt werden. Das ist möglich, da die
Bäume in ETree als Knotendisjunkt angenommen wurden. Die Knotenfolge enthält nun alle Baumknoten. Die restlichen Knoten können mit der
ursprünglichen Heuristik, die in Abschnitt 5.2.1 vorgestellt wurde, in die
Knotenfolge mitaufgenommen werden. Damit nun alle Baumkanten in die
Maximum Independent Sets aufgenommen werden, müssen diese, wie in Abschnitt 5.2.1 beschrieben, bezüglich des maximalen Gewichts der enthaltenen
Kanten bestimmt werden. Wenn man den Baumkanten ein entsprechend höheres Gewicht (z.B. das |E|-fache) als den anderen Kanten zuweist, befinden
sich alle Baumkanten in den Maximum Independent Sets und können sich
somit nicht gegenseitig überkreuzen.
Im allgemeinen Fall trifft die Annahme ETree = E↑ nicht zu. Dann kann
es passieren, dass ein Baumknoten nicht in die Knotenfolge aufgenommen
werden kann, da Knoten w mit (w, v) ∈ E↑ existieren, die noch nicht in der
Knotenfolge enthalten sind. Der Baumknoten ist dann so lange blockiert, bis
alle Knoten w in die Knotenfolge aufgenommen wurden. Dadurch kann nicht
mehr gewährleistet werden, dass die Knoten eines Baumes nacheinander, in
der Reihenfolge einer Tiefensuche, in der Knotenfolge erscheinen. In solchen
Fällen kann es passieren, dass Kreuzungen zwischen Baumkanten unvermeidlich sind. Ein Algorithmus, der auch für den allgemeinen Fall eine gültige
Knotenfolge erzeugt, stellt Algorithmus 2 dar. Er ordnet die Knoten zunächst
so an, dass für jedes Knotenpaar v,w gilt: (v, w) ∈ E↑ ⇒ π(w) < π(v), wobei
π(u) die Position des Knotens u in der Knotenfolge angibt. Diese Modifikation wird auch auf die ursprüngliche Heuristik übertragen. Dadurch wird
die Berechnung der Reihenfolge der Baumknoten vereinfacht, da die Bäume von der Wurzel aus durchlaufen werden können. Nachdem die gesamte
Knotenfolge ermittelt wurde, wird diese einfach umgedreht, womit wieder
die ursprüngliche Bedingung (v, w) ∈ E↑ ⇒ π(v) < π(w) erfüllt ist.
Ein Knoten wird als frei bezeichnet, wenn er von keinem anderen Knoten blockiert wird und noch nicht in der Knotenfolge Order enthalten ist.
Auf den Stack werden alle Wurzeln der Bäume aus ETree gelegt. Wird ein
Baumknoten v vom Stack geholt, gilt folgendes:
• Ist der Baumknoten v frei, dann wird er in die Knotenfolge aufgenommen und seine Kinder werden in zufälliger Reihenfolge auf den Stack
74
KAPITEL 6. EIN LAYOUTALGORITHMUS FÜR
UML-KLASSENDIAGRAMME
Algorithmus 2 : Berechnung der modifizierten Knotenfolge (1.Phase GT).
Eingabe: G = (V , E)
ETree , die Menge der Baumkanten
E↑ , die Menge der aufwärtsgerichteten Kanten
Ausgabe: Order, die modifizierte Knotenfolge
v ist frei ⇒ @ w : (v, w) ∈ E↑ ∧ w ∈
/ Order
VTree ← v : ∃ e ∈ ETree für die v Endpunkt ist
Order ← ∅
Stack ← die Wurzeln der Bäume von ETree in zufälliger Reihenfolge
forall v ∈ VTree do
seen[v] ← false
od
while ∃ v ∈
/ Order do
while Stack 6= ∅ do
v ← hole oberstes Element von Stack runter
seen[v] ← true
if v ist frei then
füge v in Order ein
lege alle Kinder von v in zufälliger Reihenfolge auf den Stack
forall w ∈ VTree : (w, v) ∈ E↑ ∧ w ist frei ∧ seen[w] do
lege w auf den Stack
od
fi
od
while Stack = ∅ ∧ ∃ v ∈ V \ VTree : v ∈
/ Order do
GSub ← von V \ Order induzierter Subgraph von G
if N eighbours = ∅ then
Candidates ← freie nicht Baumknoten mit minimalem Grad in GSub
else
Candidates ← freie nicht Baumknoten mit minimalem Grad in GSub
die in N eighbours sind
fi
v ← zufällig gewählter Knoten aus Candidates
füge v in Order ein
N eighbours ← alle freien Nachbarn von v die keine Baumknoten sind
forall w ∈ VTree : w ist frei do
lege w auf den Stack
od
do
do
drehe Order um
6.3. VERBESSERUNGEN DES BASISALGORITHMUS
75
gelegt. Wird dadurch ein anderer Baumknoten w frei, der bereits auf
dem Stack war (seen[w]), dann wird dieser erneut auf den Stack gelegt.
• Ist der Baumknoten v nicht frei, holt der Algorithmus den nächsten
Baumknoten vom Stack. Sobald der Knoten v frei wird, wird er wieder
auf den Stack gelegt.
Falls ETree = E↑ entsprechen die Knotenfolgen der einzelnen Bäume einer
Tiefensuche. Befinden sich keine Baumknoten auf dem Stack, weil gerade alle blockieren oder schon alle in Order enthalten sind, dann werden so lange
Nicht-Baumknoten in die Knotenfolge Order eingefügt, bis ein blockierter
Baumknoten frei wird oder alle Nicht-Baumknoten in Order eingefügt wurden. Das Einfügen der Nicht-Baumknoten erfolgt dabei mit der bestehenden
Heuristik. Der Algorithmus terminiert, da der durch die Kantenmenge E↑
induzierte Subgraph von G azyklisch ist, wodurch immer ein nicht blockierender Knoten gefunden werden kann.
Da die Liste Neighbours nur freie Nicht-Baumknoten enthält, ändert sich
deren Inhalt nicht, wenn zwischendurch Baumknoten bearbeitet werden.
Algorithmus 2 ist recht einfach gehalten. Durch die Verwendung der in
Abschnitt 5.2.1 beschriebenen Randomisierung erzielt er in der Praxis aber
gute Ergebnisse und produziert nur selten Überkreuzungen zwischen zwei
Baumkanten. Wegen der Randomisierung werden die Wurzeln der Bäume
und die Kinder eines Baumknotens in zufälliger Reihenfolge auf den Stack
gelegt. Außerdem wird der Nicht-Baumknoten aus Candidates zufällig gewählt.
Für den vorgestellten Algorithmus gilt folgendes:
• Der Algorithmus produziert eine Knotenfolge für die gilt: (v, w) ∈
E↑ ⇒ v steht vor w in der Knotenfolge. Dies ist notwendig, um die
Kantenmenge E↑ aufwärtsplanar einbetten zu können.
• Falls ETree = E↑ existieren keine Baumkanten, die sich überkreuzen.
• Falls E↑ = ∅ entspricht die Knotenfolge der Knotenfolge der ursprünglichen Heuristik.
Lemma 2 Algorithmus 2 berechnet die Knotenfolge in der Laufzeit O(|V |2 +
|E|).
Beweis:
Der Grad der Knoten im Eingabegraph sowie die Wurzeln der Bäume können
in O(|V | + |E|) bestimmt werden. Beim Einfügen eines Knotens in Order ,
muss der Grad sämtlicher Nachbarn des Knotens korrigiert werden, was
O(|V |) benötigt. Für jeden freien Baumknoten werden dessen Kinder auf
den Stack gelegt, was ebenfalls in O(|V |) erledigt werden kann. Wird ein
76
KAPITEL 6. EIN LAYOUTALGORITHMUS FÜR
UML-KLASSENDIAGRAMME
Baumknoten vom Stack genommen, weil er blockiert, dann kommt er erst
wieder auf den Stack, nachdem er frei geworden ist. Ein Baumknoten wird also höchstens zweimal auf den Stack gelegt. Die Berechnung der Knotenmenge
Candidates und Neighbours benötigt die Laufzeit O(|V |) je Iteration. Es gibt
maximal O(|V |) Iterationen, da in jeder Iteration ein Nicht-Baumknoten in
Order eingefügt wird. Also ergibt sich eine Gesamtlaufzeit von O(|V |2 +|E|).
Wenn man den initialen planaren Subgraphen durch einen minimalen
Spannbaum bestimmt, wobei die Kantenkosten so gewählt werden, dass alle
Baumkanten im minimalen Spannbaum enthalten sind, kann auf jeden Fall
erreicht werden, dass sich keine Baumkanten überkreuzen. Da der planare
Subgraph dann aber in der Regel deutlich weniger Kanten besitzt, müssen
sehr viele Kanten nachträglich geroutet werden, was die reale Laufzeit deutlich erhöhen kann.
Änderungen beim Routing
Nachdem der initiale planare Subgraph ermittelt wurde, werden die Restkanten in den Graphen geroutet. Dabei wählt man immer eine Route, die
am wenigsten Kosten verursacht. Um zu erreichen, dass Baumkanten möglichst wenige Kreuzungen mit anderen Kanten besitzen, werden deren Kreuzungskosten entsprechend erhöht. Falls nicht alle Baumkanten im planaren
Subgraph enthalten sind, wird dadurch außerdem erreicht, dass sich zwei
Baumkanten wegen der hohen Kosten nur dann kreuzen, wenn keine billigere Route gefunden werden kann. Das Zuweisen der hohen Kreuzungskosten
geschieht folgendermaßen:
Für das Routen der aufwärtsgerichteten Kanten wird der Routinggraph
verwendet. Für zwei benachbarte Faces f und g, die sich auf derselben Ebene
i befinden, enthält der Routinggraph die gerichteten Kanten (vf,i , vg,i ) und
(vg,i , vf,i ) (vgl. Abschnitt 5.2.2). Ist die Kante, die die beiden Faces f und g
auf der Ebene i abgrenzt, eine normale aufwärtsgerichtete Kante, besitzt sie
die Kosten 1. Handelt es sich bei der Kante um eine Baumkante, wird dieser
einfach ein höheres Gewicht zugewiesen.
Für das Routen der ungerichteten Kanten wird der duale Graph verwendet, dessen Kanten normalerweise die Kosten 1 besitzen. Da jede Kante
des dualen Graphs eine Kante des zugrundeliegenden Graphs repräsentiert,
können die Kosten für Kanten, die Baumkanten repräsentieren, einfach entsprechend erhöht werden.
Durch die Erhöhung der Knickkosten der Baumkanten entsprechen die
Kosten der billigsten Route im allgemeinen nicht mehr der Anzahl der entstehenden Kreuzungen beim Einfügen einer Kante. Die Laufzeit für das Routen
der Kanten verschlechtert sich durch diese Modifikation aber nicht.
6.3. VERBESSERUNGEN DES BASISALGORITHMUS
6.3.2
77
Höhenkanten
Ein Ästhetikkriterium für hierarchische Darstellungen ist die Positionierung
von Geschwisterknoten auf gleicher Höhe. Bei UML-Klassendiagrammen bietet sich das Kriterium für die Darstellung von Vererbungsbeziehungen an.
Zusammen mit den Vererbungsgabeln entstehen dann klare, schnell zu erfassende Vererbungshierarchien. Eine einheitliche Höhe von Geschwisterknoten kann allerdings nicht immer erzielt werden, da andere Kriterien, wie
z.B. die Aufwärtsrichtung von Kanten, Vorrang haben. Die hier vorgestellte
Vorgehensweise basiert darauf, „künstliche“ Kanten zwischen benachbarten
Geschwisterknoten einzufügen, die dann für eine einheitliche Höhe sorgen
sollen. Diese Kanten werden deshalb Höhenkanten genannt.
v
u1
v
u3
u1
u2
u3
u2
Abbildung 6.12: Erzeugen von Höhenkanten zwischen Geschwisterknoten.
Oft sollen nur die Geschwisterknoten einer bestimmten Kantenmenge
auf gleicher Höhe gezeichnet werden. Für den Layoutalgorithmus sind das
alle Geschwisterknoten der von der Kantenmenge ETree ∩ EHyp induzierten Bäume. Durch diese Festlegung sind Hyperkanten-Hilfsknoten die einzigsten Knoten, die Kinder besitzen, die auf gleicher Höhe platziert werden
sollen. Wenn man davon ausgeht, dass ein Hyperkanten-Hilfsknoten immer
nur gleichartige Kanten zusammenfasst, kann man folgendermaßen vorgehen:
Für jeden Hyperkanten-Hilfsknoten v ∈ VDummy , der Baumkanten zusammenfasst, werden einfach alle aufeinanderfolgenden Kinderpaare durch eine
Höhenkante verbunden, wie es in Abb. 6.12 dargestellt wird. Für jede eingefügte Höhenkante entsteht dabei ein neues Face. Wenn die Höhenkanten
horizontal und ohne Knick zwischen den Geschwisterknoten liegen, besitzen
diese eine einheitliche Höhe. Die Höhenkanten werden nach der Kompaktierung wieder aus dem Graphen entfernt.
Es gibt einige Besonderheiten, die beim Einfügen von Höhenkanten beachtet werden müssen, damit ein zufriedenstellendes Ergebnis erzielt werden
kann. Werden Höhenkanten ungünstig eingefügt, führt das oft zu schlechten
Layouts. In einigen Fällen ist es sogar besser, auf eine Höhenkante zwischen
zwei Geschwisterknoten zu verzichten.
Ein Knick einer Höhenkante führt dazu, dass die entsprechenden Geschwisterknoten nicht auf gleicher Höhe liegen, womit die Höhenkante ihren
Zweck nicht erfüllt. Deshalb erhalten die Höhenkanten während der Orthogo-
78
KAPITEL 6. EIN LAYOUTALGORITHMUS FÜR
UML-KLASSENDIAGRAMME
nalisierung höhere Knickkosten als normale ungerichtete Kanten. Dazu wird
die Kostenfunktion von Abschnitt 6.2.3 so erweitert, dass jede Höhenkante
die Kosten cf + 1 erhält.
Wird eine Höhenkante knickfrei gezeichnet, sorgt sie für eine einheitliche
Höhe der dazugehörigen Geschwisterknoten, da sie dann horizontal zwischen
ihren Endpunkten liegen muss. Eine knickfreie Höhenkante kann nicht vertikal zwischen ihren Endpunkten liegen, da die ausgehenden Baumkanten der
Geschwisterknoten höhere Kosten besitzen und die Höhenkante somit einen
Kandinsky-Knick bekommen würde.
Die Höhenkanten können erst nach der Einbettung der aufwärtsgerichteten Kanten eingefügt werden, da die Ordnung der Geschwisterknoten feststehen muss. Beim Einfügen einer Höhenkante sollte vermieden werden, dass
das innere Face, das durch die beiden Kanten von den Geschwisterknoten
zum Vater und der Höhenkante begrenzt wird, Knoten enthält. Ansonsten
führt die Höhenkante dazu, dass die Geschwisterknoten weiter entfernt von
ihrem Vater platziert werden und die Vererbungshierarchie dadurch unübersichtlicher wird. Um die Höhenkanten geeignet einfügen zu können, routet
man sie deshalb nicht über den dualen Graph, sondern fügt sie durch direkte
Modifikation der betreffenden Faces ein. Für alle benachbarten Geschwisterknoten, die auf einer einheitlichen Höhe platziert werden sollen, geht man
folgendermaßen vor:
• Falls einer der beiden Geschwisterknoten neben der Vererbungskante
noch eine weitere ausgehende, aufwärtsgerichtete Kante besitzt, sollte
keine Höhenkante eingefügt werden. Dies hat folgenden Grund: Wegen der kreuzungsminimalen Einbettung werden die aufwärtsgerichteten Kanten oft seitlich an der Vererbungsstruktur vorbeigeführt. Wie
Abb. 6.13(a) zeigt, könnte dann eine Höhenkante zwischen den Knoten u1 und u2 auf keinen Fall ihren Zweck erfüllen. Eine Höhenkante
zwischen den Knoten u2 und u3 würde dazu führen, dass die Knoten
u3 und u4 weiter weg vom Vaterknoten platziert würden. Dieser Effekt
würde auch eintreten, falls die aufwärtsgerichtete Kante von u2 nicht
seitlich an der Vererbungsstruktur vorbeigeführt wird, sondern unter
dieser liegt. Die einzigste Ausnahme, wo eine Höhenkante sinnvoll wäre, ist, wenn der Knoten mit der aufwärtsgerichteten Kante am Rand
liegt und die Kante an der entsprechenden Seite vorbeigeführt wird,
wie beim Knoten u5.
• Existiert schon eine ungerichtete Kante zwischen zwei benachbarten
Geschwisterknoten im Eingabegraph, dann sollte keine zusätzliche Höhenkante eingefügt werden. Ansonsten würden Knicke entstehen, da im
Kandinsky-Modell keine Kanten mit denselben Endpunkten vollständig parallel verlaufen können. Die bestehende Kante stellt in diesem
Fall schon eine Art „natürliche“ Höhenkante dar (vgl. Abb. 6.13(b)).
Man weist solchen Kanten deshalb dieselben Knickkosten zu wie den
6.3. VERBESSERUNGEN DES BASISALGORITHMUS
79
Höhenkanten. Da die ungerichteten Kanten aber über den dualen Graph
geroutet werden, kann nicht gewährleistet werden, dass diese „günstig“
eingebettet werden.
v
w2
w3
w1
v
u5
u1
u3
u4
u1
u2
(a)
v
w1
u1
u2
w2
(c)
w3
u3
(b)
w1
u3
u2
u1
v
v
u2
w2
(d)
u3
u1
u2
u3
w
(e)
Abbildung 6.13: Verschiedene Fälle, die beim Einfügen von Höhenkanten
auftreten können. Die Höhenkanten sind gestrichelt gezeichnet, die aufwärtsgerichteten Kanten besitzen einen Pfeil und die Baumkanten sind zusätzlich
dick gezeichnet. Die restlichen Kanten werden durch normale Linien repräsentiert. Ein schwarzer Punkt kennzeichnet eine Kreuzung.
• Wenn auf die Höhenkante nicht schon wegen einer der beiden vorherigen Punkte verzichtet wurde, fügt man sie so ein, dass ein Face aus den
Kanten der beiden Geschwisterknoten zu ihrem Vater und der Höhenkante entsteht. Weitere inzidente Kanten der Geschwisterknoten liegen
damit außerhalb des Faces (vgl. Abb. 6.13(c)). Solche Faces können nur
erzeugt werden, wenn die beiden Kanten von den Geschwisterknoten
zum Vater keine Kreuzungen besitzen. Wird eine der beiden Kanten
gekreuzt, verzichtet man auf eine Höhenkante (Abb. 6.13(d)). Solche
Fälle treten aufgrund der gewählten Kreuzungskosten aber eher selten
auf.
Kann die Höhenkante entsprechend eingefügt werden, ist die einheitliche Höhe der Geschwisterknoten gewährleistet, falls keine nachfolgend
80
KAPITEL 6. EIN LAYOUTALGORITHMUS FÜR
UML-KLASSENDIAGRAMME
geroutete Kante mehr das Face verändert. Damit Höhenkanten möglichst selten gekreuzt werden, erhalten sie höhere Kreuzungskosten als
normale ungerichtete Kanten (vgl. Abschnitt 6.3.1).
Die Laufzeit der vorgestellten Vorgehensweise setzt sich folgendermaßen
zusammen: Der Algorithmus läuft alle Knoten v ∈ VDummy , die Baumkanten
zusammenfassen, ab und schaut sich deren Kindknoten an. Vor dem Einfügen einer Höhenkante zwischen zwei benachbarten Geschwisterknoten muss
an beiden Knoten überprüft werden, ob eine weitere ausgehende, aufwärtsgerichtete Kante existiert, ob die ausgehende Baumkante von einer anderen
Kante gekreuzt wird und ob schon eine ungerichtete Kante zwischen den
Geschwisterknoten existiert. Die Überprüfungen gehen in O(|V | + c). Es existieren maximal O(|V |) benachbarte Geschwisterpaare. Das Teilen des Faces
beim Einfügen einer Höhenkante geht in der Laufzeit O(|V |+c). Da eine Höhenkante durch Kreuzungen geteilt sein kann, müssen nach der Kompaktierung O(|V | + c) Kanten aus dem Graph entfernt werden. Die Gesamtlaufzeit
beträgt somit O(|V |2 + |V | · c).
Bis jetzt wurde das Konzept nur auf Geschwisterknoten, der von der Kantenmenge ETree ∩ EHyp induzierten Bäume angewendet. Sollen dagegen alle
Geschwisterknoten, der von der Kantenmenge ETree induzierten Bäume, auf
einer einheitlichen Höhe positioniert werden, können nicht mehr einfach alle
benachbarten Geschwisterknoten durch eine Höhenkante verbunden werden.
Es existieren jetzt nämlich auch Geschwisterknoten, die nicht durch Kanten
aus ETree entstanden sind und somit nicht auf der gleichen Höhe gezeichnet werden sollen. Dadurch wird das geschickte Einfügen von Höhenkanten
erschwert. Abb. 6.13(e) zeigt eine Möglichkeit, wie man in diesem Fall die
Höhenkante einfügen kann. Da dieser Fall häufig auftreten kann, können die
Höhenkanten nicht einfach weggelassen werden.
Soll das Konzept auf alle Geschwisterknoten, des von der Kantenmenge E↑ induzierten Graphen, angewendet werden, muss außerdem folgendes
beachtet werden: Da der Subgraph im allgemeinen keinen Baum darstellt,
kann ein Knoten mehrere ausgehende, aufwärtsgerichtete Kanten und somit auch Geschwister von verschiedenen Vätern besitzen. Das Konzept kann
dann nicht mehr ohne weiteres angewendet werden.
Da die Knoten unterschiedliche Größen besitzen und sie jeweils mit ihrem
Mittelpunkt auf dem Gitter angeordnet werden, bedeutet eine einheitliche
Höhe von Geschwisterknoten also eine einheitliche Höhe der Mittelpunkte
der Knoten. Wenn die einheitliche Höhe von Geschwisterknoten in der Kompaktierungsphase realisiert wird, kann das Problem besser gelöst werden, da
die Kompaktierung die unterschiedliche Größe der Knoten berücksichtigt.
Auch die anderen aufgetretenen Probleme können eventuell besser in der
Kompaktierungsphase gelöst werden.
6.3. VERBESSERUNGEN DES BASISALGORITHMUS
6.3.3
81
Behandlung von Selbstschleifen
Für die Bestimmung des planaren Subgraphen durch die GT-Heuristik werden die Selbstschleifen aus dem Graphen genommen. Danach werden sie normalerweise wie gewöhnliche ungerichtete Kanten, die sich noch nicht im planaren Subgraph befinden, in den Graphen geroutet. Während der Orthogonalisierung wird ihre Form durch den Netzwerkfluss bestimmt. Diese Vorgehensweise hat folgenden Nachteil: Bei einer ungünstigen Einbettung kann es
vorkommen, dass die Selbstschleifen ein schlechtes Layout mit vielen Knicken
bekommen (vgl. Abb. 6.14(a)). Gerade wenn sich mehrere Selbstschleifen an
einem Knoten befinden, was bei UML-Klassendiagrammen durchaus üblich
ist, enstehen dann unleserliche Zeichnungen. Um solche Layouts zu verhindern, kann man die Selbstschleifen erst nach der Orthogonalisierung einfügen,
bevor die Zeichnung kompaktiert wird. Durch diese Vorgehensweise ergeben
sich folgende Vorteile:
4
3
4
3
1
1
2
(a)
2
(b)
Abbildung 6.14: Zwei alternative Platzierungen einer Selbstschleife.
• Während der Einbettungsphase müssen weniger ungerichtete Kanten
in den Graphen geroutet werden.
• Das zu lösende Netzwerkflussproblem enthält weniger Knoten und Kanten (jede Selbstschleife erzeugt ein neues Face).
• Da die Form der restlichen Kanten nach der Orthogonalisierung bereits
feststeht, kann die Selbstschleife an einer geeigneten Stelle am Knoten,
mit einer geeigneten Form, platziert werden (vgl. Abb. 6.14(b)).
KAPITEL 6. EIN LAYOUTALGORITHMUS FÜR
UML-KLASSENDIAGRAMME
82
O0
O1
O2
O0
L2
R0
L1
R1
L0
R2
O1
O2
L2
R0
L1
R1
L0
U2
U1
(a)
U0
R2
U2
U1
U0
(b)
Abbildung 6.15: Aufteilung der Kanten auf die Ports und mögliche Anordnung der Selbstschleifen.
Bevor der modifizierte Einfügealgorithmus vorgestellt wird, wird der Begriff „Port“ erläutert. Ein Port ist ein Anschluss eines Knotens, an dem
sich Kanten befinden können (vgl. Abb. 6.15). Jede Knotenseite besitzt drei
Ports. Die drei Ports der oberen Knotenseite werden mit O0, O1 und O2
bezeichnet. An den Ports O1, R1, U1 und L1 liegt die nicht knickendene Mittelkante. An den Ports O0, R0, U0 und L0 liegen die Kanten, die vom Knoten
aus gesehen nach links knicken, an den Ports O2, R2, U2 und L2 die Kanten
die nach rechts knicken. Natürlich müssen nicht alle Ports belegt sein.
Der nun beschriebene Einfügealgorithmus für Selbstschleifen verwendet
die vier verschiedenen Positionierungsmöglichkeiten, die in Abb. 6.15(b) zu
sehen sind. Er nutzt dabei folgende Eigenschaft der Selbstschleifen aus: Eine
Selbstschleife kann stets, unabhängig von den anderen Kanten des Knotens,
an einer beliebigen Ecke des Knotens platziert werden, ohne dass dabei Überkreuzungen mit anderen Kanten entstehen. Durch eine solche Platzierung
besitzt jede Selbstschleife genau drei Knicke, was der minimalen Anzahl von
Knicken einer Selbstschleife im Kandinsky-Modell entspricht.
Um die günstigste Ecke für eine Selbstschleife zu finden, wird Algorithmus 3 verwendet. Mit O werden die drei Ports O0, O1 und O2 an der Oberseite
des Knotens bezeichnet. Analog werden die drei Ports der anderen Seiten mit
L, U und R bezeichnet. |O0| gibt die Anzahl der Kanten an, die den Port O0
belegen, |O| die Anzahl aller Kanten, die von der Oberseite ausgehen. Es
gilt also |O|=|O0|+|O1|+|O2|. Außerdem ist |O2+R0| eine Abkürzung für
|O2|+|R0|. |Ecke| bzw. |Seiten| gibt die Anzahl der Kanten an, die an den
Ports der entsprechenden Variablen liegen.
Der Algorithmus platziert eine Selbstschleife an einer Ecke mit möglichst
wenigen Kanten. Zur Bestimmung einer geeigneten Ecke wird neben der Anzahl der Kanten an der Ecke, auch die Anzahl der Kanten an den beiden Seiten der Ecke berücksichtigt. Der Algorithmus versucht also eine gleichmäßige
6.3. VERBESSERUNGEN DES BASISALGORITHMUS
83
Algorithmus 3 : Platzierung einer Selbstschleife.
Eingabe: die Ports eines Knotens v und deren Kardinalität
Ausgabe: Ecke, enthält günstigste Position für die Selbstschleife
Ecke ← O2,R0
Seiten ← O,R
if |Ecke| > |R2+U0| ∨ |Ecke| = |R2+U0| ∧ |Seiten| > |R+U| then
Ecke ← R2,U0
Seiten ← R,U
fi
if |Ecke| > |U2+L0| ∨ |Ecke| = |U2+L0| ∧ |Seiten| > |U+L| then
Ecke ← U2,L0
Seiten ← U,L
fi
if |Ecke| > |L2+O0| ∨ |Ecke| = |L2+O0| ∧ |Seiten| > |L+O| then
Ecke ← L2,O0
Seiten ← L,O
fi
Kantenverteilung um den Knoten zu erreichen, da diese zu übersichtlicheren
Zeichnungen führt. Die Variable Ecke beinhaltet die beiden Ports, an denen
die Selbstschleife platziert werden soll. Beim Einfügen einer Selbstschleife
muss die orthogonale Repräsentation entsprechend modifiziert werden. Jede Selbstschleife erzeugt dabei ein neues Face. Die Form der Selbstschleife
entspricht je nach Platzierung einer der Formen aus Abb. 6.15(b).
Für Knoten mit mehreren Selbstschleifen existieren zwei verschiedene
Vorgehensweisen:
• Alle Selbstschleifen eines Knotens werden an derselben Ecke platziert.
• Für jede Selbstschleife eines Knotens wird die geeignetste Position von
neuem bestimmt.
Es wird angenommen, dass sich die Anzahl der Mehrfachkanten linear
zu O(|V |) verhält. Das Finden und Entfernen der Selbstschleifen aus dem
Eingabegraph benötigt O(|E|), was mit O(|V |+c) abgeschätzt werden kann.
Das Bestimmen der Anzahl der Kanten an den Ports der Knoten geht in
O(|V | + c). Das Bestimmen der Position einer Selbstschleife geht in O(1)
und das Einfügen sämtlicher Selbstschleifen in O(|V | + c). Somit ergibt sich
eine Gesamtlaufzeit von O(|V | + c).
KAPITEL 6. EIN LAYOUTALGORITHMUS FÜR
UML-KLASSENDIAGRAMME
84
6.4
Der gesamte Algorithmus
Im folgenden wird ein Überblick über die einzelnen Schritte des entwickelten
Layoutalgorithmus gegeben. Anschließend erfolgt die Ermittlung der Laufzeit des Algorithmus.
6.4.1
Überblick
Der folgende Überblick unterscheidet die Phasen Vorverarbeitung, Planarisierung, Orthogonalisierung, Kompaktierung und Nachverarbeitung. Jeder
modifizierte Schritt enthält einen Verweis auf den Abschnitt, in dem die Änderungen erläutert wurden. Der entwickelte Layoutalgorithmus besteht aus
folgenden Schritten:
Vorverarbeitung:
• Zerlegung des Eingabegraphen in seine Zusammenhangskomponenten, für die der Algorithmus dann separat durchgeführt wird.
Die folgenden Schritte beziehen sich immer auf den durch eine
Zusammenhangskomponente gegebenen Graph.
• Transformation der Hyperkanten (→ Abschnitt 6.1).
• Aufwärtsrichten von ungerichteten Kanten, um eine einheitliche
Orientierung der aufwärtsgerichteten Kanten zu gewährleisten (→
Abschnitt 6.2.4).
• Entfernen der Selbstschleifen aus dem Graphen.
Planarisierung:
• Entfernen der Mehrfachkanten.
• Erstellen des planaren Subgraphen mit der modifizierten GTHeuristik (→ Abschnitt 6.3.1).
• Wiedereinfügen der Mehrfachkanten.
• Routen der aufwärtsgerichteten Kanten, die nicht im planaren
Subgraphen enthalten sind (→ Abschnitt 6.3.1).
• Einfügen der Höhenkanten (→ Abschnitt 6.3.2).
• Routen der restlichen Kanten, die noch nicht im planaren Subgraphen sind (→ Abschnitt 6.3.1).
6.4. DER GESAMTE ALGORITHMUS
85
Orthogonalisierung:
• Zuweisung der Kantenform für die aufwärtsgerichteten Kanten
(→ Abschnitt 6.2.1).
• Entfernen unnötiger Knicke (→ Abschnitt 6.2.2).
• Aufstellen des Kandinsky-Netzwerks, unter Berücksichtigung der
vorgegebenen Winkel und Knicke (→ Abschnitt 6.2.3).
• Lösen des Netzwerkflussproblems und Erstellen der quasi-orthogonalen Repräsentation.
• Einfügen der Selbstschleifen (→ Abschnitt 6.3.3).
Kompaktierung:
• Kompaktieren der orthogonalen Repräsentation und Platzierung
der Beschriftungen.
Nachbearbeitung:
• Entfernung der zusätzlich in den Graphen eingefügten Knoten
und Kanten. Darunter fallen Kreuzungsknoten, Höhenkanten und
Hyperkanten-Hilfsknoten.
• Anordnung der einzelnen Zusammenhangskomponenten des Eingabegraphen durch einen entsprechenden Algorithmus.
6.4.2
Laufzeit
Wenn man vom Zerlegen des Eingabegraphen in die Zusammenhangskomponenten und von deren Wiederzusammenfügen absieht, ergibt sich für das
Layouten eines zusammenhängenden Graphen G = (V, E) mit dem hier vorgestellten Algorithmus folgende Laufzeit: Die Vorverarbeitung wird durch
das Berechnen des minimalen Spannbaumes für die einheitliche Ausrichtung
der aufwärtsgerichteten Kanten dominiert und benötigt somit O(|E|
log |V |).
Die Planarisierung besitzt die Laufzeit O |V ||E|2 + |E| · (|V | + c)2 , wobei c
die Anzahl der Kantenkreuzungen angibt.
Die Laufzeit der Orthogonalisie
rung beträgt O (|V | + c)2 log (|V | + c) , die der Kompaktierung
O |V | + c .
Die Nachverarbeitung benötigt die Laufzeit O |V | + c . Daraus resultiert
eine Gesamtlaufzeit von O |V ||E|2 + |E| · (|V | + c)2 .
In der Praxis hat sich gezeigt, dass der entwickelte Layoutalgorithmus
für Graphen mit bis zu 100 Knoten schnell genug ist, um ein Klassendiagramm ohne größere Verzögerung zu layouten. Dabei wird allerdings von
86
KAPITEL 6. EIN LAYOUTALGORITHMUS FÜR
UML-KLASSENDIAGRAMME
einem dünnen Graphen ausgegangen (|E| = O(|V |)), was auf die meisten
UML-Graphen zutrifft. Damit die Klassendiagramme übersichtlich bleiben,
wird normalerweise für jedes Paket ein extra Diagramm erzeugt. Die meisten
UML-Klassendiagramme besitzen deshalb weniger als 100 Knoten und lassen
sich mit dem entwickelten Layoutalgorithmus zufriedenstellend layouten.
Kapitel 7
Implementierung
Die Implementierung des Layoutalgorithmus erfolgt in der Programmiersprache Java unter Verwendung der yFiles-Klassenbibliothek. Die yFilesKlassenbibliothek von yWorks1 stellt eine in Java implementierte, effiziente
Klassenbibliothek zur Graphenvisualisierung dar, die Datenstrukturen, Algorithmen und Funktionalität für Graphen bereitstellt [33].
Der Layoutalgorithmus wurde in den Jar-Inspector2 integriert. Der JarInspector ist ein Tool zum Visualisieren von UML-Klassendiagrammen. Die
Klassendiagramme werden durch die Analyse von Java-Bytecode erstellt,
der in Form von class- oder jar-Dateien (Java Archive) vorliegen kann. Der
Jar-Inspector dient vor allem der Demonstration von verschiedenen Layoutalgorithmen und besitzt deswegen nur eine eingeschränkte Funktionalität. Er unterscheidet Klassen, Schnittstellen und Pakete, sowie folgende
Beziehungen: Klassen- und Schnittstellenvererbung, Schnittstellenimplementierung, Abhängigkeiten zwischen Paketen und Assoziationen, die durch die
Attribute der Klassen definiert werden. Ein Diagramm zeigt den Inhalt eines Pakets an. Ein Paket kann wiederum andere Pakete enthalten. Durch
Klicken auf eines dieser Pakete kann der Benutzer interaktiv durch die unterschiedlichen Klassendiagramme der Pakethierarchie navigieren. Abb. 7.1
zeigt die graphische Oberfläche des Jar-Inspectors.
Im nächsten Abschnitt wird zunächst das Design des Layoutalgorithmus
beschrieben. Anschließend werden einige Details für dessen Verwendung im
Jar-Inspector erläutert.
7.1
Design des Layoutalgorithmus
In diesem Abschnitt werden die wesentlichen Klassen, aus denen der Layoutalgorithmus besteht, kurz beschrieben und deren Zusammenwirken aufgezeigt. Der Übersicht halber werden dabei keine Schnittstellen und Klassen,
1
2
http://www.yworks.com
http://www-pr.informatik.uni-tuebingen.de/c/forschung/uml/jarinspector.xml
88
KAPITEL 7. IMPLEMENTIERUNG
Abbildung 7.1: Grafische Oberfläche des Jar-Inspectors.
die lediglich Datenstrukturen repräsentieren, berücksichtigt. Abb. 7.2 zeigt
ein Klassendiagramm der beschriebenen Klassen.
Die Klasse ConstrainedKandisky bildet die Rahmenklasse des Layoutalgorithmus. Sie verwendet die Klasse GroupingManager, um die Hyperkantenmodellierung für die Vererbungsgabeln und die einheitliche Ausrichtung der
aufwärtsgerichteten Kanten vorzunehmen. Die Ablaufsteuerung des Layoutvorganges wird an die Klasse KandinskyFramework delegiert. Zur Realisierung der drei Phasen des Topology-Shape-Metrics Ansatzes verwendet diese
die Klassen MixedCombinatorialEmbedder, UpwardKandinskyLayouter und
KanCompactor. Die Klasse SelfLoopTool wird verwendet, um die Selbstschleifen zu entfernen bzw. nach der Orthogonalisierung wieder einzufügen.
Existieren mehrere Selbstschleifen an einem Knoten, werden diese alle an
derselben Ecke platziert.
Die Klasse MixedCombinatorialEmbedder ermittelt eine aufwärtsplanare
Einbettung des Eingabegraphen. Die Verwaltung der Mehrfachkanten wird
dabei von der Klasse MixedMultipleEdgeTool realisiert. Die Bestimmung
des planaren Subgraphen erfolgt mit der GT-Heuristik und wird an die Klasse
MixedGT delegiert. Diese verwendet die Klasse MixedVertexOrder, um die
Knotenfolge der ersten Phase zu ermitteln. Das Einfügen und Entfernen der
Höhenkanten übernimmt die Klasse HeightConstraints.
7.1. DESIGN DES LAYOUTALGORITHMUS
89
ConstrainedKandinsky
GroupingManager
MixedCombinatorialEmbedder
MixedGT
HeightConstraints
KandinskyFramework
KanCompactor
MixedMultipleEdgeTool
UpwardKandinskyLayouter
Shape2ConstraintsTransformer
SelfLoopTool
ConstrainedLayouter
MixedVertexOrder
Abbildung 7.2: UML-Klassendiagramm der verwendeten Klassen.
Die Orthogonalisierung erfolgt durch die Klasse UpwardKandinskyLayouter. Diese legt die Form der aufwärtsgerichteten Kanten fest und führt
die Knickreduzierung durch. Anschließend wird die ermittelte Form durch
die Klasse Shape2ConstraintTransformer auf die dazugehörigen Winkel
und Knicke transformiert. Das Aufstellen und Lösen des Min-Cost-FlowProblems, sowie das Erzeugen der quasi-orthogonalen Repräsentation wird
in der Klasse ConstrainedLayouter implementiert.
Die Klasse KanCompactor ist für die Kompaktierung der Zeichnung und
die Zuweisung der Koordinaten zuständig.
Die Klassen KandinskyFramework, MixedCombinatorialEmbedder,
MixedGT und KanCompactor waren bereits implementiert und mussten nur
noch entsprechend modifiziert werden.
Die Klasse ConstrainedLayouter basiert auf einer bestehenden Klasse, die das ursprüngliche Kandinsky-Netzwerk implementierte. Zusätzlich
können jetzt auch Winkel zwischen Kanten sowie Kantenknicke vorgegeben werden. Ein Layoutalgorithmus kann nun die gewünschte Form in die
dazugehörigen Winkel und Knicke umwandeln und diese dann der Klasse ConstrainedLayouter vorgeben. Die Klasse UpwardKandinskyLayouter
verwendet für diese Transformation die Klasse Shape2ConstraintTransformer.
Die Klassen ConstrainedKandisky, GroupingManager, UpwardKandinskyLayouter und Shape2ConstraintTransformer befinden sich im Paket yext.layout.orthogonal.mixed. Die Klassen MixedCombinatorialEmbedder, MixedMultipleEdgeTool, HeightConstraints, MixedGT und
MixedVertexOrder werden für die aufwärtsplanare Einbettung benötigt und
sind deshalb im Paket yext.layout.orthogonal.upwardplanar unterge-
90
KAPITEL 7. IMPLEMENTIERUNG
bracht. Das Paket y.layout.orthogonal.kandinsky enthält Klassen, die
vom allgemeinen Kandinsky-Modell verwendet werden. Dazu gehören u.a.
die Klassen KandinskyFramework, KanCompactor, SelfLoopTool und ConstrainedLayouter.
7.2
Anwendung des Layoutalgorithmus
Nachdem der Jar-Inspector gestartet wurde, kann man durch Drücken der
linken Schaltfläche auf der Registerkarte „Project“ (die mit „a“ markierte
Schaltfläche aus Abb. 7.3), einen Dateidialog öffnen. Sobald ein Verzeichnis
oder eine jar-Datei ausgewählt wurde, anaylsiert der Jar-Inspector den Bytecode und erzeugt das Klassendiagramm der obersten Ebene. Damit das
Klassendiagramm mit dem entwickelten Layoutalgorithmus gezeichnet wird,
muss das Auswahlfeld in der Werkzeugleiste auf „Orthogonal“ gesetzt werden (das mit „b“ markierte Auswahlfeld). Durch das Drücken der Schaltfläche
rechts neben dem Auswahlfeld (die mit „c“ markierte Schaltfläche), wird der
Layoutvorgang manuell gestartet. Durch das Klicken auf ein Paket, wird ein
neues Klassendiagramm erzeugt, das den Inhalt des Pakets darstellt. Um
wieder auf die höhere Ebene zurückzukehren, klickt man einfach auf den
Hintergrund.
Abbildung 7.3: Bedienung des Jar-Inspectors.
7.2. ANWENDUNG DES LAYOUTALGORITHMUS
91
Für das Layouten von UML-Klassendiagrammen mit dem entwickelten
Algorithmus, bietet der Jar-Inspector außerdem folgende Wahlmöglichkeiten:
• Eine Auswahl, welche Beziehungsarten dargestellt werden sollen. Die
Auswahl findet über den Menüpunkt „Diagram“→ „Diagram Options“
statt (mit „e“ markiert).
• Eine Auswahl, ob Methoden und Attribute angezeigt werden sollen.
Auch diese Auswahl findet über den Menüpunkt „Diagram“→„Diagram
Options“ statt.
• Für jede Art von Vererbungsbeziehung kann festgelegt werden, ob die
betreffenden Kanten aufwärtsgerichtet gezeichnet werden sollen. Außerdem können die Kanten als Vererbungsgabeln oder gewöhnlich dargestellt werden. Sollen die Kanten als Vererbungsgabeln aber nicht
unbedingt aufwärtsgerichtet dargestellt werden, werden sie erst nach
der Ausrichtung aufwärtsgerichtet. Dadurch können Vererbungsgabeln
entstehen, die nicht ausgerichtet sind (vgl. Abb. 7.4). Zu der Auswahl
gelangt man durch Drücken der rechtesten Schaltfläche der Werkzeugleiste (die mit „d“ markierte Schaltfläche).
«interface»
IIOParamController
ImageWriteParam
−controller
IIOParam
ImageReadParam
ImageTypeSpecifier
−destinationType
type
ImageIO.CanEncodeImageAndFormatFilter
−defaultController
ImageTypeSpecifier.Interleaved
ImageTypeSpecifier.Banded
ImageTypeSpecifier.Indexed
ImageTypeSpecifier.Packed
ImageTypeSpecifier.Grayscale
Abbildung 7.4: Nicht ausgerichtete Vererbungsgabeln.
92
KAPITEL 7. IMPLEMENTIERUNG
Kapitel 8
Zusammenfassung und
Bewertung
In dieser Diplomarbeit wurde ein Layoutalgorithmus für UML-Klassendiagramme vorgestellt, der auf dem Topology-Shape-Metrics Ansatz basiert. Die
Anforderungen an den Layoutalgorithmus wurden aus der UML-Notation
und den ermittelten Ästhetikkriterien abgeleitet. Der Schwerpunkt dieser
Arbeit lag dabei auf dem aufwärtsgerichteten Zeichnen von Kanten sowie
der Verwendung von Vererbungsgabeln zur Darstellung der Vererbungshierarchie. Es wurde gezeigt welche Form den aufwärtsgerichteten Kanten dazu
zugewiesen werden muss und wie diese durch das Netzwerk umgesetzt werden kann. Dabei wurde auch ein Algorithmus zur Knickreduzierung und zur
einheitlichen Ausrichtung der aufwärtsgerichteten Kanten vorgestellt. Der
Layoutalgorithmus wurde außerdem durch die Verwendung einer optimierten
Einbettung, das Einfügen von Höhenkanten und einer speziellen Behandlung
der Selbstschleifen verbessert. Die Implementierung erfolgte in der Programmiersprache Java unter Verwendung der yFiles-Klassenbibliothek. Schließlich
wurde gezeigt, wie der Layoutalgorithmus im Jar-Inspector verwendet werden kann.
Der entwickelte Layoutalgorithmus ermittelt eine quasi-orthogonale Git
tereinbettung des Eingabegraphen in der Laufzeit O |V ||E|2 +|E|·(|V |+c)2 .
Er unterscheidet die Kantenmengen E↑ , ETree und EHyp , wobei die Kanten
aus EHyp als Vererbungsgabeln und die Kanten aus E↑ aufwärtsgerichtet
dargestellt werden. Kanten aus ETree sind Baumkanten, die besonders hervorgehoben werden sollen und deshalb bei der Einbettung und der Formgebung bevorzugt behandelt werden. Die Zuordnung der Kantenmengen eines
UML-Graphs zu diesen drei Kantenmengen ist flexibel. Es muss sich lediglich
um veträgliche Kantenmengen handeln. Dadurch besteht die Möglichkeit,
z.B. nur die Klassenvererbung aufwärtsgerichtet zu zeichnen oder alle Implementierungsbeziehungen durch Vererbungsgabeln darzustellen. Werden keine
Kanten auf die Menge der aufwärtsgerichteten Kanten abgebildet, produziert
94
KAPITEL 8. ZUSAMMENFASSUNG UND BEWERTUNG
der Algorithmus eine gewöhnliche orthogonale Zeichnung. Der Layoutalgorithmus kann also verschiedenen Ästhetikpräferenzen berücksichtigen.
Um den Eingabegraphen einzubetten, berechnet der entwickelte Layoutalgorithmus zuerst einen planaren Subgraphen. Dabei kommt eine modifizierten Version der GT-Heuristik zum Einsatz. Anschließend werden die
Restkanten in den Subgraphen geroutet. Die Orthogonalisierung basiert auf
dem Kandinsky-Modell. Für die Kompaktierung wurden keine speziellen Anpassungen durchgeführt.
Der Algorithmus berücksichtigt die wesentlichen, ermittelten Ästhetikkriterien. Die Kanten der Menge E↑ besitzen eine einheitliche Kantenrichtung und die Vererbungshierarchie kann durch Vererbungsgabeln dargestellt
werden. Die Minimierung der Anzahl der Kreuzungen und die Minimierung
der Anzahl der Knicke, erfolgt unter Berücksichtigung der zuvor genannten
Kriterien. Durch die Kompaktierung wird die Fläche der gegebenen Form
möglichst klein gehalten. Falls möglich, werden Geschwisterknoten in Vererbungshierarchien auf derselben Höhe gezeichnet. Der vorgestellte Algorithmus erzeugt keine Überlappungen zwischen Knoten. Um n-fach Beziehungen
darzustellen, kann das hier vorgestellte Hyperkantenkonzept entsprechend
erweitert werden. Kommentarknoten v mit δ(v) = 1 werden bereits ohne
zusätzliche Modifikation nahe am dazugehörigen Knoten platziert.
Die Qualität des Layouts hängt von mehreren Faktoren ab. Ein wesentlicher Faktor ist die Anzahl der aufwärtsgerichteten Kanten, da diese zusätzliche Kantenkreuzungen und Kantenknicke verursachen. Je weniger Kantenknicke und Winkel vorgeschrieben werden, desto besser verhält sich der Algorithmus bezüglich dieser Kriterien. Ein weiterer Faktor ist die Dichte des
Graphen. Sehr dichte Graphen mit vielen Kanten pro Knoten führen oft zu
unübersichtlichen Zeichnungen. Da im verwendeten Kandinsky-Modell maximal eine Kante pro Knotenseite gerade gezeichnet werden kann, enthält
die Zeichnung dann schon viele Kandinsky-Knicke.
Die Minimierung der Anzahl der Kreuzungen erfolgt in der ersten Phase des Topology-Shape-Metrics Ansatzes. Knicke werden erst in der zweiten Phase bestimmt. Dies führt zu einigen unschönen Zeichnungen, da eine
Kante unter Umständen mehrere Knicke erhält, die durch eine zusätzliche
Kreuzung hätten verhindert werden können. Wegen der Trennung der beiden
Phasen, kann man solche Effekte kaum verhindern. Sie stellen eine Schwäche des Topology-Shape-Metrics Ansatzes dar. Durch eine Art Rerouting
nach der Orthogonalisierung könnte man versuchen das Resultat eventuell
zu verbessern.
Abb. 8.1(a) zeigt eine Schwäche der verwendeten Einbettung. Die markierte Kante muss nicht aufwärtsgerichtet gezeichnet werden und kann deshalb auch an einer anderen Seite des Knotens platziert werden. Dann könnte die Kante ohne Knick gezeichnet werden. Abb. 8.1(b) zeigt eine weitere
Schwäche. Würde sich die markierte eingehende Kante rechts von der anderen eingehenden Kante befinden, dann könnte sie mit wenigeren Knicken
+core
+coreLayouter
+coreLayouter
95
gezeichnet werden. Eine Einbettung, die bestimmte Regeln anwendet und die
Struktur um die einzufügende Kante berücksichtigt, könnte in beiden Fällen
zumindest zu lokalen Verbesserungen führen.
«implements»
LabelLayoutTranslator
«implements»
AbstractLayoutStage
BendConverter
BufferedLayouter
ComponentLayouter
SelfLoopLayouter
SubgraphLayouter
ParallelEdgeLayouter
«interface»
LayoutOrientation
+this$0 OrientationLayouter.PortTransformer
«implements»
OrientationLayouter
(a)
«interface»
ProfitModel
«implements»
«implements»
LabelLayoutDataRefinement
CompositeLayoutStage
BufferedLayouter
LabelRanking
+this$0
LabelLayoutDataRefinement.SemiSliderProfitModel
(b)
Abbildung 8.1: Schwächen der Einbettung.
Die erzeugten Zeichnungen können überflüssige Knicke besitzen. Dies
liegt daran, dass der Algorithmus, der die Formzuweisung berechnet, zum
Zeitpunkt der Zuweisung der Kantenform keine Informationen über die Lage der anderen Knoten berücksichtigt. Der Knickreduzierungsalgorithmus
entfernt außerdem nur Knicke, die immer entfernt werden können. Hier liegt
also noch Verbesserungspotential. Durch Algorithmen, die auch topologische Eigenschaften der anderen Knoten berücksichtigen, können noch einige
Knicke verhindert werden. Es bietet sich auch an, eine Art Knickreduzierung
nach der Orthogonalisierung durchzuführen, da dann die Form aller Kanten
feststeht. Da maximal eine Kante pro Knotenseite gerade gezeichnet werden kann, führt das Kandinsky-Modell zu mehreren Knicken, auch wenn das
Aufgrund der unterschiedlichen Knotengrößen nicht immer erforderlich ist.
Eine Schwäche des allgemeinen orthogonalen Netzwerks zeigt Abb. 8.2.
Die Zeichnung ist kreuzungs- und knickminimal. Beim Realisieren der Winkel schickt ein Knoten beide Einheiten in dasselbe Face, wodurch ein 270
Grad Winkel entsteht. Das liegt daran, dass beim Berechnen des minimalen
96
KAPITEL 8. ZUSAMMENFASSUNG UND BEWERTUNG
Kostenflusses immer möglichst viel Fluss entlang eines billigsten Pfades geschickt wird. Durch ein leichtes Erhöhen der Kosten der zweiten Flusseinheit,
könnte man das abändern.
2
3
6
7
1
10
9
5
8
4
Abbildung 8.2: Entstandene Schneckenform.
Für die Kompaktierung wurden keine speziellen Anpassungen vorgenommen. Es würde sich jedoch z.B. anbieten, die einheitliche Höhe von Geschwisterknoten in der Kompaktierungsphase zu realisieren.
Der entwickelte Algorithmus kann auch zur Darstellung anderer Diagrammarten eingesetzt werden. Durch die flexible Zuordnung der Kanten des zu
zeichnenden Graphs auf die Kantenmengen E↑ , ETree und EHyp , können einige Diagrammarten bereits ohne weitere Modifikationen ansprechend gezeichnet werden. Die meisten der erläuterten Konzepte sind allgemein anwendbar.
Die hier vorgestellte Behandlung der Selbstschleifen bringt sogar schon für
allgemeine Graphen eine Verbesserung. Die Vorgehensweise zur Erzielung
der Aufwärtsplanarität von teilgerichteten Graphen im Kandinsky-Modell
kann ebenfalls häufig eingesetzt werden. Da außerdem viele Diagrammarten
versuchen Hierarchien zu veranschaulichen, kann auch die spezielle Behandlung der Baumkanten oftmals verwendet werden. Für solche Diagrammarten
bietet sich dann auch der Einsatz von Höhenkanten an. Auch das vorgestellte
Hyperkantenkonzept kann für viele Diagrammarten sinnvoll eingesetzt werden. Die Form, die der Algorithmus den aufwärtsgerichteten Kanten zuweist,
kann für andere Diagrammarten entsprechend angepasst werden. Der Algorithmus, der die Formzuweisung berechnet, stellt die spezifischte Änderung
dar. Die Kosten für Knicke und Kreuzungen wurden bis jetzt immer für ganze Kantenmengen festgelegt. Wenn man den Algorithmus so modifiziert, dass
man jeder Kante eigene Knick- und Kreuzungskosten zuweisen kann, dann
bietet sich eine sehr flexible Handhabung für andere Diagrammarten. Das erweiterte Netzwerk, das die Vorgabe von Winkeln und Knicken erlaubt, kann,
wie in [3] beschrieben, auch dazu verwendet werden, um aus einer Skizze
einer Zeichnung eine orthogonale Zeichnung zu erstellen.
Für den Layoutalgorithmus bieten sich außerdem folgende Erweiterungsmöglichkeiten an:
97
• Berücksichtigung von dynamischen Ästhetikkriterien.
• Clustern von zusammengehörigen Elementen.
98
KAPITEL 8. ZUSAMMENFASSUNG UND BEWERTUNG
Anhang A
Beispieldiagramme
IOHandler
ImageOutputHandler
JPGIOHandler
LinkMap
+references
ImageMapOutputHandler
TGFIOHandler
YGFIOHandler
GMLIOHandler
GIFIOHandler
(a)
IOHandler
ImageOutputHandler
ImageMapOutputHandler
TGFIOHandler
YGFIOHandler
GMLIOHandler
+references
JPGIOHandler
GIFIOHandler
LinkMap
(b)
Abbildung A.1: Klassendiagramm, das ohne einheitliche Höhe der Geschwisterknoten (a) bzw. mit einheitlicher Höhe der Geschwisterknoten (b) gezeichnet wurde.
100
ANHANG A. BEISPIELDIAGRAMME
«interface»
YCursor
«implements»
«interface»
YList.ListCursorImpl
EdgeCursor
«interface»
NodeCursor
«implements»
«implements»
«implements»
«implements»
Node.EdgeCursorImpl
Node.SemiEdgeCursorImpl
EdgeList.EdgeListCursorImpl
«interface»
GraphObjectCursor
NodeList.NodeListCursorImpl
«implements»
«implements»
Node.NodeCursorImpl
«implements»
GraphObjectList.GraphObjectCursorImpl
Node.SemiNodeCursorImpl
(a)
«interface»
YCursor
«implements»
«interface»
YList.ListCursorImpl
EdgeCursor
«implements»
«implements»
«implements»
«interface»
EdgeList.EdgeListCursorImpl
Node.SemiEdgeCursorImpl
NodeCursor
Node.EdgeCursorImpl
«implements»
«interface»
Node.SemiNodeCursorImpl
GraphObjectCursor
«implements»
«implements»
Node.NodeCursorImpl
«implements»
GraphObjectList.GraphObjectCursorImpl
NodeList.NodeListCursorImpl
(b)
Abbildung A.2: Klassendiagramm, das mit einem hierarchischen (a) bzw.
mit dem entwickelten Layoutalgorithmus (b) gezeichnet wurde.
101
«interface»
«interface»
IInformation
IUMLInformation
edgeinfo
0..1
Edge
0..1
nodeinfo
Node
«interface»
Graph
IMetaObject
UMLAssociationInfo
UMLInheritanceInfo
«interface»
INodeInformation
associationClass
UMLNodeInfo
*
attributs
methods
associationClass
«interface»
IEdgeInformation
UMLClassMethodInfo
1
UMLClassAttributInfo
1
represents
1
1
1
UMLEdge
MetaClassAttribut
represents
1
*
1
UMLNode
MetaClassMethod
1
represents
UMLGraph
1
MetaObject
MetaNode
represents
1
MetaEdge
represents
1
MetaGraph
nodes
1
MetaPackage
nodes
1
MetaCluster
IUMLEdgeInformation
(a)
«interface»
IMetaObject
Graph
«implements»
MetaObject
MetaClassAttribut
MetaEdge
MetaCluster
MetaClassMethod
MetaPackage
UMLGraph
MetaNode
MetaStereodef
«interface»
IInformation
«interface»
«interface»
IEdgeInformation
INodeInformation
«implements»
«implements»
UMLClassMethodInfo
Edge
«implements»
IUMLEdgeInformation
«implements»
Node
UMLEdge
UMLClassAttribugInfo
UMLNodeInfo
UMLNode
«interface»
IUMLInformation
«implements»
«implements»
UMLAssociationInfo
UMLInheritanceInfo
(b)
Abbildung A.3: Klassendiagramm, das mit einem in [11] vorgestellten hierarchischen Ansatz (a) bzw. mit dem entwickelten Layoutalgorithmus (b) gezeichnet wurde.
MetaGraph
MetaStereodef
102
ANHANG A. BEISPIELDIAGRAMME
«interface»
IIOParamController
ImageWriteParam
−controller
IIOParam
ImageReadParam
ImageTypeSpecifier
−destinationType
type
ImageIO.CanEncodeImageAndFormatFilter
−defaultController
ImageTypeSpecifier.Interleaved
ImageTypeSpecifier.Banded
ImageTypeSpecifier.Indexed
ImageTypeSpecifier.Packed
ImageTypeSpecifier.Grayscale
(a)
ImageTypeSpecifier
ImageIO.CanEncodeImageAndFormatFilter
type
−destinationType
«interface»
IIOParamController
IIOParam
−controller
ImageWriteParam
ImageReadParam
−defaultController
ImageTypeSpecifier.Interleaved
ImageTypeSpecifier.Banded
ImageTypeSpecifier.Indexed
ImageTypeSpecifier.Packed
ImageTypeSpecifier.Grayscale
(b)
Abbildung A.4: Klassendiagramm, das ohne einheitliche Ausrichtung der
aufwärtsgerichteten Kanten (a) bzw. mit einheitlicher Ausrichtung der aufwärtsgerichteten Kanten (b) gezeichnet wurde. Die markierte Kante stellt
die künstlich gerichtete Kante dar.
103
«implements»
−computeKernel
−computeKernel
GenericPolygon
AbstractComputeKernel
HomPolygon
YPolygon
+YKERNEL
«interface»
Kernel
HomComputeKernel
+defaultKernel
«implements»
YKernel
«implements»
HomKernel
SlowDoubleKernel
(a)
«implements»
−computeKernel
−computeKernel
GenericPolygon
+w
AbstractComputeKernel
+y
YPolygon
HomPolygon
«interface»
HomComputeKernel
Kernel
+defaultKernel
«implements»
«implements»
YKernel
+YKERNEL
HomKernel
SlowDoubleKernel
(b)
Abbildung A.5: Klassendiagramm, das mit der herkömmlichen (a) bzw. mit
der modifizierten (b) Behandlung der Selbstschleifen gezeichnet wurde.
104
ANHANG A. BEISPIELDIAGRAMME
Servant
«interface»
DynamicImplementation
ServantManagerOperations
«interface»
«interface»
ServantManager
ServantActivatorOperations
«interface»
ServantLocatorOperations
«implements»
«implements»
«interface»
ServantActivatorPOA
ServantActivator
ServantLocatorPOA
«implements»
_ServantActivatorStub
«interface»
ServantLocator
«implements»
_ServantLocatorStub
(a)
Servant
«interface»
DynamicImplementation
ServantManagerOperations
«interface»
«interface»
«interface»
ServantManager
ServantActivatorOperations
ServantLocatorOperations
«implements»
«interface»
ServantActivator
«implements»
ServantActivatorPOA
ServantLocatorPOA
«implements»
_ServantActivatorStub
«interface»
ServantLocator
«implements»
_ServantLocatorStub
(b)
Abbildung A.6: Klassendiagramm, das ohne die spezielle Behandlung der
Baumkanten (a) bzw. mit der speziellen Behandlung der Baumkanten (b)
gezeichnet wurde.
Literaturverzeichnis
[1] Balzert, H.: Lehrbuch der Objektmodellierung. Analyse und Entwurf .
Spektrum Akademischer Verlag, Juli 1999.
[2] Binucci, C., W. Didimo, G. Liotta und M. Nonato: Labeling Heuristics for Orthogonal Drawings. In: Proceedings of the 9th International
Symposium on Graph Drawing (GD’2001), Bd. 2275 d. Reihe LNCS , S.
139–153, 2001.
[3] Brandes, U., M. Eiglsperger, M. Kaufmann und D. Wagner:
Sketch-Driven Orthogonal Graph Drawing. In: Proceedings of the 10th
International Symposium on Graph Drawing (GD’2002), Bd. 2528, S.
1–12. Springer, 2002.
[4] Bronštein, I. N., K. A. Semendâev, G. Musiol und H. Mühlig: Taschenbuch der Mathematik . Verlag Harri Deutsch, Frankfurt am
Main, Fourth Aufl., 1999.
[5] Cimikowski, R.: An analysis of heuristics for the maximum planar
subgraph problem. In: Proceedings of the 6th ACM-SIAM Symposium of
Discrete Algorithms, S. 322–331, 1995.
[6] Coleman, M. K. und D. S. Parker: Aesthetics-based Graph Layout for Human Consumption. Software – Practice and Experience,
26(12):1415–1438, 1996.
[7] Corman, T. H., C. E. Leiserson und R. L. Rivest: Introduction to
Algorithms. MIT Press/McGraw-Hill, 1990.
[8] Di Battista, G., W. Didimo, M. Patrignani und M. Pizzonia:
Orthogonal and Quasi-upward Drawings with Vertices of Prescribed Size. In: Kratochvil, J. (Hrsg.): Proceedings of the 7th International
Symposium on Graph Drawing (GD’99), Bd. 1731 d. Reihe LNCS , S.
297–310. Springer, 1999.
[9] Di Battista, G., P. Eades, R. Tamassia und I. G. Tollis: Graph
Drawing: Algorithms for the Visualization of Graphs. Prentice Hall,
1999.
106
LITERATURVERZEICHNIS
[10] Eades, P., W. Lai, K. Misue und K. Sugiyama: Preserving the Mental Map of a Diagram. In: Proceedings of Compugraphics ’91 , S. 24–33,
1991.
[11] Eichelberger, H.: Automatisches Zeichnen von UML Klassendiagrammen mit dem Sugiyama-Algorithmus in Tagungsband des GIWorkshops Softwarevisualisierung 2000 . Techn. Ber. A/01/2000, Universität des Saarlandes, 2000.
[12] Eichelberger, H.: Aesthetics of Class Diagrams. In: Proc. of the First
IEEE International Workshop on Visualizing Software for Understanding and Analysis, Vissoft 2002 , S. 23–31, 2002.
[13] Eiglsperger, M., S. Fekete und G. Klau: Orthogonal Graph Drawing. In: Kaufmann, M. und D. Wagner (Hrsg.): Drawing Graphs:
Methods and Models, LNCS Tutorial, S. 121–171. Springer, 2001.
[14] Eiglsperger, M. und M. Kaufmann: An Approach for Mixed Upward Planarization. In: Proceedings of the 7th International Workshop
on Algorithms and Datastructures (WADS 2001), S. 352–364. Springer,
2001.
[15] Eiglsperger, M. und M. Kaufmann: Fast Compaction for Orthogonal Drawings with Vertices of Prescribed Size. In: Graph Drawing, S.
124–138, 2001.
[16] Eiglsperger, M., M. Kaufmann und M. Siebenhaller: A
Topology-Shape-Metrics Approach for the Automatic Layout of UML
Class Diagram. ACM Symp. on Software Visualization’2003, to appear.
[17] Eppinger, F.: Kombinatorische Einbettung teilgerichteter Graphen.
Diplomarbeit, Wilhelm-Schickard-Institut für Informatik, Arbeitsbereich für Paralleles Rechnen, Universität Tübingen, April 2001.
[18] Fößmeier, U. und M. Kaufmann: Drawing high degree graphs with
low bend numbers. In: Brandenburg, F. (Hrsg.): Graph Drawing
(Proc. GD ’95), Bd. 1027 d. Reihe LNCS , S. 254–266. Springer, 1996.
[19] Fowler, M. und K. Scott: UML Distilled: Applying the Standard
Object Modeling Language. Addison-Wesley, 1997.
[20] Gibbons, A.: Algorithmic Graph Theory. Cambridge University Press,
1985.
[21] Goldschmidt, O. und A. Takvorian: An Efficient Graph Planarization Two-Phase Heuristic. Networks, 24:69–73, 1994.
LITERATURVERZEICHNIS
107
[22] Klau, G. W. und P. Mutzel: Combining Graph Labeling and Compaction. In: Kratochvil, J. (Hrsg.): Proceedings of the 7th International Symposium on Graph Drawing (GD’99), Nr. 1731 in LNCS , S.
27–37. Springer, 1999.
[23] Klein, P. N., S. Rao, M. Rauch und S. Subramanian: Faster
shortest-path algorithms for planar graphs. In: Proceedings ACM Symp.
on Theory of Computing, 1994.
[24] OMG: Unified Modeling Language. Specification v1.4, Object Management Group, 2001. http://www.omg.org/uml/.
[25] Purchase, H. C.: Which Aesthetic has the Greatest Effect on Human
Understanding? . In: Proceedings of the 5th International Symposium on
Graph Drawing (GD’97), Bd. 1353 d. Reihe LNCS , S. 248–261, 1997.
[26] Purchase, H. C., J.-A. Allder und D. Carrington: Graph Layout Aesthetics in UML Diagrams: User Preferences. Journal of Graph
Algorithms and Applications, 2002.
[27] Purchase, H. C., L. Colpoys, M. McGill, D. Carrington und
C. Britton: UML Class Diagram Syntax: An Empirical Study of Comprehension. In: Proceedings of the Australian Symposium on Information Visualisation, Sydney, Australia, 2001. Australian Computer Society
Inc.
[28] Purchase, H. C., M. McGill, L. Colpoys und D. Carrington:
Graph Drawing Aesthetics and the Comprehension of UML Class Diagrams: An Empirical Study. In: Proceedings of the Australian Symposium on Information Visualisation, Sydney, Australia, 2001. Australian
Computer Society Inc.
[29] Resende, M. und C. Ribeiro: A GRASP for graph planarization.
Networks, 29:173–189, 1997.
[30] Tamassia, R.: On Embedding a Graph in the Grid with the Minimum
Number of Bends. SIAM Journal on Computing, 16(3):421–444, 1987.
[31] Tamassia, R.: Graph Drawing.
In: Goodman, J. E. und
J. O’Rourke (Hrsg.): CRC Handbook of Discrete and Computational
Geometry. CRC Press, 1997.
[32] Tamassia, R., G. D. Battista und C. Batini: Automatic graph drawing and readability of diagrams. IEEE Transactions on Systems, Man
and Cybernetics, 18(1):61–79, 1988.
108
LITERATURVERZEICHNIS
[33] Wiese, R., M. Eiglsperger und M. Kaufmann: yFiles: Visualization and Automatic Layout of Graphs. In: Proceedings of the 9th International Symposium on Graph Drawing (GD’01), LNCS, S. 453–454.
Springer, 2001.
Herunterladen