10 Graphenalgorithmen in Java

Werbung
10 Graphenalgorithmen in Java
10.1 Implementierung eines gewichteten Graphen
10.2 Implementierung der Breitensuche
10
10.3 Implementierung der Tiefensuche
147
10 Graphenalgorithmen in Java
Teil X
Graphalgorithmen in Java
Überblick
Implementierung eines gewichteten Graphen
Implementierung der Breitensuche
Implementierung der Tiefensuche
Saake/Schallehn
Algorithmen & Datenstrukturen II
10–1
Implementierung eines gewichteten Graphen
◮
◮
Grundprinzip: Adjazenzliste
(Angepasste) Implementierung aus Buch
◮
◮
◮
◮
◮
Durch Adjazenliste keine Knoten-Klasse erforderlich
Benannte Knoten für eindeutigen Zugriff
Wichtung von Kanten erfordert extra Kantenklasse
Umgegestellt auf Java Generics
Bugfixes ;-)
◮
Original-Code: siehe Buch bzw. zugehörige Web-Seite
◮
Angepasster Code: auf Web-Seite zur Vorlesung
Saake/Schallehn
148
Algorithmen & Datenstrukturen II
10–2
Uni Magdeburg, WS 2005/06
10 Graphenalgorithmen in Java
Graphen-Klasse
◮
◮
labels für Zugriff auf Knoten nach Namen
nodes implementiert Adjazenliste als Liste von Liste von
Kanten
public class WeightedGraph {
...
private HashMap<String,Integer> labels;
private List<List<Edge> > nodes;
...
Saake/Schallehn
Algorithmen & Datenstrukturen II
10
}
10–3
Graphen-Klasse /2
public void addNode(String label) {
if (labels.containsKey(label))
throw new NodeAlreadyDefinedException();
nodes.add(new ArrayList<Edge>());
int idx = nodes.size() - 1;
labels.put(label, new Integer(idx));
}
Saake/Schallehn
Algorithmen & Datenstrukturen II
10–4
Graphen-Klasse /3
public void addEdge(String src, String dest,
int cost) {
adjList = nodes.get(getNodeID (src));
adjList.add (
new Edge (getNodeID(dest), cost));
}
Saake/Schallehn
Algorithmen & Datenstrukturen II
Uni Magdeburg, WS 2005/06
10–5
149
10 Graphenalgorithmen in Java
Graphen-Klasse /4
public int getNodeID(String label) {
Integer i = labels.get(label);
if (i == null)
throw new NoSuchElementException();
return i.intValue();
}
Saake/Schallehn
Algorithmen & Datenstrukturen II
10–6
Kanten-Klasse
◮
Speicherung der Zuordnung von Gewichten zu Zielknoten
static class Edge {
int dest, cost;
public Edge(int d, int c) {
dest = d;
cost = c;
}
}
Saake/Schallehn
Algorithmen & Datenstrukturen II
10–7
Testrahmen: ungerichteter Graph
public static void main(String[] args) {
WeightedGraph g1 = new WeightedGraph();
g1.addNode(”r”); g1.addNode(”s”);
g1.addNode(”t”); g1.addNode(”u”);
g1.addNode(”v”); g1.addNode(”w”);
g1.addNode(”x”); g1.addNode(”y”);
g1.addEdge(”s”, ”r”, 1); g1.addEdge("r", ß", 1);
g1.addEdge(”r”, ”v”, 1); g1.addEdge("v", "r", 1);
g1.addEdge(”s”, ”w”, 1); g1.addEdge("w", ß", 1);
g1.addEdge(”w”, ”t”, 1); g1.addEdge("t", "w", 1);
g1.addEdge(”w”, ”x”, 1); g1.addEdge("x", "w", 1);
g1.addEdge(”t”, ”u”, 1); g1.addEdge(ü", "t", 1);
g1.addEdge(”t”, ”x”, 1); g1.addEdge("x", "t", 1);
g1.addEdge(”u”, ”y”, 1); g1.addEdge("y", ”u”, 1);
g1.addEdge(”x”, ”y”, 1); g1.addEdge("y", "x", 1);
System.out.println(g1);
...
Saake/Schallehn
150
Algorithmen & Datenstrukturen II
10–8
Uni Magdeburg, WS 2005/06
10 Graphenalgorithmen in Java
Testrahmen: gerichteter Graph
Saake/Schallehn
"x", 1);
"y", 1);
"y", 1);
ß", 1);
Algorithmen & Datenstrukturen II
10
WeightedGraph g2 = new WeightedGraph();
g2.addNode(”u”);
g2.addNode(”v”);
g2.addNode(”w”);
g2.addNode(”x”);
g2.addNode(”y”);
g2.addNode(”z”);
g2.addEdge(”u”, ”v”, 1); g2.addEdge(”u”,
g2.addEdge(”x”, ”v”, 1); g2.addEdge("v",
g2.addEdge(”y”, ”x”, 1); g2.addEdge("w",
g2.addEdge(”z”, ”z”, 1); g2.addEdge("w",
g2.searchDepthFirst();
10–9
Implementierung der Breitensuche
◮
◮
BFS = BreadthFirstSearch
Implementierung als iterativer Algorithmus
◮
◮
◮
Konstanten für Farbmarkierungen
Klasse BFSItem für Traversierungszustände einzelner
Knoten
Algorithmus unter Verwendung einer Warteschlange
Saake/Schallehn
Algorithmen & Datenstrukturen II
10–10
Implementierung der Breitensuche /2
public class WeightedGraph {
public final static int WHITE = 0;
public final static int GRAY = 1;
public final static int BLACK = 2;
...
static class BFSItem {
int color, distance, prev;
...}
...
public void searchBreadthFirst(int start) {
...
}
...
}
Saake/Schallehn
Algorithmen & Datenstrukturen II
Uni Magdeburg, WS 2005/06
10–11
151
10 Graphenalgorithmen in Java
Implementierung der Breitensuche /3
◮
Speichert für einen Knoten: Farbe (Weiß, Grau, Schwarz),
Distanz zum Ursprungsknoten, Vorgängerknoten im
aufspannenden Baum
static class BFSItem {
int color, distance, prev;
public BFSItem(int c, int d, int p) {
color = c; distance = d; prev = p;
}
}
Saake/Schallehn
Algorithmen & Datenstrukturen II
10–12
Algorithmus Breitensuche /1
public void searchBreadthFirst(int start) {
int i;
BFSItem[] table = new BFSItem[labels.size()];
Queue<Integer> queue = new LinkedList<Integer>();
for (i = 0; i < table.length; i++)
table[i] = new BFSItem(WHITE,
Integer.MAX_VALUE, -1);
table[start].color = GRAY;
table[start].distance = 0;
queue.offer(start);
...
Saake/Schallehn
Algorithmen & Datenstrukturen II
10–13
Algorithmus Breitensuche /2
...
while (! queue.isEmpty()) {
int u = (queue.poll()).intValue();
Iterator iter = getEdges(u);
while (iter.hasNext()) {
Edge v = (Edge)iter.next();
if (table[v.dest].color == WHITE) {
table[v.dest].color = GRAY;
table[v.dest].distance =
table[u].distance + v.cost;
table[v.dest].prev = u;
queue.offer(v.dest);
}
}
table[u].color = BLACK;
}
}
Saake/Schallehn
152
Algorithmen & Datenstrukturen II
10–14
Uni Magdeburg, WS 2005/06
10 Graphenalgorithmen in Java
Implementierung der Tiefensuche
◮
DFS = DepthFirstSearch
◮
Implementierung als rekursiver Algorithmus
◮
Nicht-rekursive Einstiegsmethode zum sicherstellen, dass
alle Knoten erreicht werden
Klasse DFSItem für Traversierungszustände einzelner
Knoten
Saake/Schallehn
Algorithmen & Datenstrukturen II
10
◮
10–15
Implementierung der Tiefensuche /2
◮
Speichert für einen Knoten: Farbe (Weiß, Grau, Schwarz),
Vorgängerknoten im aufspannenden Baum, Beginn und
Ende der Bearbeitung
static class DFSItem {
int color, prev, d, f;
public DFSItem() {
color = WHITE; prev = 0;
d = f = 0;
}
}
Saake/Schallehn
Algorithmen & Datenstrukturen II
10–16
Algorithmus Tiefensuche /1
public void searchDepthFirst() {
int i, t = 0;
DFSItem[] table = new DFSItem[labels.size ()];
for (i = 0; i < table.length; i++)
table[i] = new DFSItem();
for (i = 0; i < table.length; i++)
if (table[i].color == WHITE)
dfsVisit (i, t, table);
}
Saake/Schallehn
Algorithmen & Datenstrukturen II
Uni Magdeburg, WS 2005/06
10–17
153
10 Graphenalgorithmen in Java
Algorithmus Tiefensuche /2
private int dfsVisit(int u,
int time, DFSItem[] table) {
table[u].color = GRAY;
table[u].d = ++time;
Iterator iter = getEdges(u);
while (iter.hasNext()) {
Edge v = (Edge)iter.next();
if (table[v.dest].color == WHITE) {
table[v.dest].prev = u;
time = dfsVisit(v.dest, time, table);
}
}
table[u].color = BLACK;
table[u].f = ++time;
return time;
}
Saake/Schallehn
154
Algorithmen & Datenstrukturen II
10–18
Uni Magdeburg, WS 2005/06
Herunterladen