WS 2008/09 Diskrete Strukturen Prof. Dr. J. Esparza Lehrstuhl für Grundlagen der Softwarezuverlässigkeit und theoretische Informatik Fakultät für Informatik Technische Universität München http://www7.in.tum.de/um/courses/ds/ws0809 Kapitel IV – Graphentheorie • Graphentheorie – Grundlagen – Bäume – Eigenschaften von Graphen – Graphen-Algorithmen – Matchings 2 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Wir präsentieren einige Grundverfahren der algorithmischen Graphentheorie. • Diese Verfahren werden als ``Bausteine´´ in vielen Algorithmen verwendet. • Die Verfahren beantworten auch einige Grundfragen: – Welche Knoten sind aus einem gegebenen Knoten erreichbar? – Welcher ist der kürzeste Weg zwischen zwei gegebenen Knoten? – Wie findet man einen optimalen Spannbaum? (gewichtete Graphen) 3 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Suchverfahren Verfahren zum Durchlaufen aller Knoten n o h eines Graphen, die aus einem gegebenen d b Knoten erreichbar root a c sind. e i 4 m g q j p r f k Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München l Kapitel IV – Graphen; Algorithmen • Generischer Algorithmus Suche – Zwei Datenstrukturen: • Tabelle: speichert für jeden Knoten die Information, ob er schon besucht wurde, und eventuell auch zusätzliche Informationen. Initialisierung: nur die Wurzel ist besucht worden. • Worklist: enthält die schon besuchten, aber noch nicht bearbeiteten Knoten. Initialisierung: die Worklist enthält nur die Wurzel. 5 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Generischer Suchalgorithmus Initialisierung; while die Worklist nicht leer ist wähle einen Knoten v aus der Worklist; falls v mindestens einen unbesuchten Nachbarn hat wähle einen unbesuchten Nachbarn u von v; markiere u als besucht; (trage die zus. Inf. für u in die Tabelle ein); trage u in die Worklist ein andernfalls entferne v aus der Worklist 6 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen 13 o d 4 1 e p 15 11 17 m 12 a q j 18 r root 9 i 7 3 b 14 n h8 c 2 g6 16 f k 5 7 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München l 10 Kapitel IV – Graphen; Algorithmen • Suchvarianten 8 Suchstrategie: Strategie zur Wahl von v. – Kaotische Suche: Wähle v beliebig. – Breitensuche: FIFO-Strategie (First In First Out). Wähle v als der Knoten, der zuerst in die Worklist kam (unter denjenigen, die zur Zeit in der Worklist sind). – Tiefensuche: LIFO-Strategie (Last In First Out). Wähle v als der Knoten, der zuletzt in die Worklist kam (unter denjenigen, die zur Zeit in der Worklist sind). Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Beispiel o n h d m b root a e i c g q j p r f k 9 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München l Kapitel IV – Graphen; Algorithmen • Mögliche zusätzliche Informationen, die in der Tabelle für jeden besuchten Knoten gespeichert werden können: – Vorgänger Nachbarn, aus dem der Knoten besucht wurde. (Im Algorithmus, der Vorgänger von u ist v.) – Suchtiefe • 0 für die Wurzel • (1 + Suchtiefe des Vorgängers) für die anderen Knoten. 10 – Suchnummer Laufende Nummer für die besuchten Knoten. Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Erweiterter Suchalgorithmus Initialisierung; nà 1; n[s] à n; d[s] à 0; für alle v2 V\{s} n[v],d[v] à 1; while die Worklist nicht leer ist wähle einen Knoten v aus der Worklist; falls v mindestens einen unbesuchten Nachbarn hat wähle einen unbesuchten Nachbarn u von v; markiere u als besucht; nà n+1; n[u]à n; d[u] à d[v]+1; pred[u] à v; trage u in die Worklist ein andernfalls entferne v aus der Worklist 11 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Satz: 12 Sei G=(V,E) mit Wurzel s eine Eingabe für den generischen Suchalgoritmus. 1. Der Suchalgorithmus terminiert nach höchstens |V| Durchläufe der while-Schleife. 2. Nach Terminierung sind alle aus s erreichbaren Knoten von G als besucht markiert. 3. Wenn G zusammenhängend ist, dann bilden die Vorgänger-Kanten {v, pred[v]}, v V \ {s} einen Spannbaum von G. Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Beweis: 1. Wir haben: • Jeder Knoten von G kommt höchstens einmal in die Worklist. • Jede Ausführung der while-Schleife entfernt einen Knoten aus der Worklist. Es folgt, dass die while-Schleife höchstens |V|-Mal ausgeführt wird. 13 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Beweis: 2. Sei v einen aus s erreichbaren Knoten. Dann gibt es einen Pfad s=v0 v1 … vn=v. Der Beweis ist durch Induktion über n. Basis: n=0. Dann v=s und s wird in der Initialisierung als besucht markiert. Schritt: n>0. Aus der Induktionsannahme folgt, dass vn-1 irgendwann als besucht markiert wird. Es folgt, dass irgendwann vn-1 in die Worklist kommt und irgendwann aus der Worklist entfernt wird (nach Terminierung ist die Worklist leer). Wenn vn-1 aus der Worklist entfernt wird, sind alle Nachbarn von vn-1 schon markiert. 14 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Beweis: 15 3. Für jede Kante {v, pred[v]} gilt: • pred[v] ist aus s durch Vorgänger-Kanten erreichbar. • pred[v] hat eine kleinere Suchnummer als v. Es folgt, dass der Graph der Vorgänger-Kanten zusammenhängend ist, und dass die VorgängerKanten keinen Kreis bilden. Damit ist dieser Graph ein Baum. Da G zusammenhängend ist und 2. gilt, gibt es für jeden Knoten v von G eine Kante {v, pred[v]} . Damit ist der Baum ein Spannbaum. Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Breitensuche 13 o d 4 m 12 a 1 e 15 q j 18 p 11 17 root 9 i 7 r 3 b 14 n h8 c 2 g6 16 f k 16 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München 5 l 10 Kapitel IV – Graphen; Algorithmen • Spannbaum der Breitensuche. a c f l g k m n d b h e o q r 17 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München i p j Kapitel IV – Graphen; Algorithmen • Breitensuche Lemma: In einer Breitensuche für G = (V,E) gilt: 1. Wenn u vor v aus der Worklist kommt, dann gilt d[u] · d[v]. 2. Zu jedem Zeitpunkt gibt es eine Zahl k, so dass für alle Knoten v in die Worklist gilt: k · d[v] · k+1. 3. Wenn {u,v} 2 E, dann d[u] · d[v]+1. 18 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Breitensuche Satz: Am Ende einer Breitensuche für G = (V,E) gilt: 1. d[v] ist die Länge des kürzesten s-v-Pfades in G. Wenn es keinen s-v-Pfad gibt, dann d[v]=1 2. Für alle erreichbaren Knoten v, der s-v-Pfad im Spannbaum der Suche ist ein kürzester s-v-Pfad. 19 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Breitensuche Beweis von 1: – Es gibt einen s-v-Pfad der Länge d[v]: Sei s=v0 v1 … vn=v der s-v-Pfad im Spannbaum. Die Länge des Pfades ist n. Für alle 0· i <n, gilt: d[vi+1] = d[vi]+1. Mit d[s]=0 folgt d[v]=n. Für jeden s-v-Pfad s = v0 v1… vn = v gilt: d[v] · n. Es gilt (Lemma, dritter Teil): d[v] = d[vn] ≤ d[vn-1]+1 ≤ d[vn-2]+2 ≤ … ≤ d[v0]+k = k. 20 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Breitensuche Beweis von 2: – Folgt aus dem Beweis von 1: der s-v-Pfad im Spannbaum hat Länge d[v], und diese ist auch die Länge des kürzesten s-v-Pfades. 21 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Eine Implementierung von Breitensuche Eingabe: Graph G = (V,E), Startknoten s V. Ausgabe: Felder d[v], pred[v] für alle v V. for all v V do begin if v = s then d[v] 0; else d[v] ; pred[v] NULL; end … // bearbeite alle Knoten aus V // wenn wir am Startknoten sind // setze seinen Abstand auf 0 // setze alle anderen Abstände auf // setze alle Vorgänger auf „undefiniert“ 22 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Fortsetzung nächste Seite Kapitel IV – Graphen; Algorithmen • Eine Implementierung von Breitensuche … Q new QUEUE; Q.INSERT(s); while not Q.IsEMPTY() do begin v Q.DEQUEUE(); for all u (v) do if d[u] = then begin d[u] d[v] + 1; pred[u] v; Q.INSERT(u); end end // legt ein neues Objekt vom Typ Warteschlange an // fügt das Element s in die Warteschlange ein // teste, ob noch Elemente in der Queue // hole nächstes Element aus der Queue // betrachte alle Nachbarn von v // der Knoten u ist noch unbesucht // sein Abstand = Abstand Vorg. + 1 // sein Vorgänger ist v // setze ihn in die Warteschlange 23 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Tiefensuche o 17 d 9 a 1 e q 10 p 24 11 14 m 13 root 8 i r 18 b 7 n 15 h 16 c 2 g 6 12 f j 3 k 5 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München l 4 Kapitel IV – Graphen; Algorithmen • Spannbaum der Tiefensuche a c f l k q b g n h i p m e j r 25 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München o d Kapitel IV – Graphen; Algorithmen • Eine Implementierung von Tiefensuche Eingabe: Graph G = (V,E), Sartknoten s Ausgabe: Feld pred[v] für alle v V. for all v V do pred[v] NULL; … 26 V. // bearbeite alle Knoten aus V // setze alle Vorgänger auf „undefiniert“ Fortsetzung nächste Seite Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Algorithmus Tiefensuche (Fortsetzung) … S new STACK; // legt ein neues Objekt vom Typ STACK an v s; repeat if u (v) \ {s} mit pred[u] = NULL then // nicht besuchter Nachf. ? S.PUSH(v) // setze Element auf den Stack pred[u] v; // das Element ist Vorgänger von u v u; // mache mit u weiter else if not S.IsEMPTY() then v S.POP(); // hole Element vom Stack else v NULL; until v = NULL; // wiederhole bis Stack leer 27 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Kürzeste Wege – Gegeben sind ein Graph G = (V,E) und eine Gewichtsfunktion w : E ℝ+ {+ }. – O. B. d. A. sei G vollständig und damit auch zusammenhängend. – Sei u = v0, v1,..., vn = v ein Pfad in G. Die Länge dieses n1 Pfades ist w(vi , vi 1). i 0 28 – d(u, v) sei die Länge eines kürzesten Pfades von u nach v. Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Kürzeste Wege Problemstellungen: – Gegeben u, v V , berechne d(u, v). – Gegeben u V , berechne für alle v V die Länge d(u, v) eines kürzesten Pfades von u nach v (sssp, single source shortest path). – Berechne für alle (u, v) V die kürzeste Entfernung d(u, v) (apsp, all pairs shortest path). 29 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Dijkstras Algorithmus für sssp. F V for all v F do d[v] p[v] // d: aktuell kürzeste Pfade null // p: Vorgängerliste d[s] = 0; while F // der Startknoten do bestimme u F F mit d[u] minimal; F \ {u}; for all v (u) do if d[v] > d[u] + w(u,v) then 30 d[v] d[u] + w(u,v) p[v] u Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Satz: Dijkstras Algorithmus berechnet d(s,v) für alle v 2 V; der Zeitaufwand ist O(|V|2). Beweis: Zeitbedarf ist aus dem Algorithmus ersichtlich. Es ist auch klar, dass nach Terminierung d[v] ¸ d(s,v) für alle Knoten v gilt. Für jeden Knoten v, sei tv der Zeitpunkt unmittelbar vor der Entfernung von v aus F. Wir zeigen: zum Zeitpunkt tv gilt d[v] · d(s,v). Daraus folgt, dass d[v] · d(s,v) auch nach Terminierung gilt, und damit d[v]=d(s,v). Der Beweis ist durch Widerspruch: 31 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen Beweis (Forts.): Annahme: Es gibt einen Knoten v, für den zum Zeitpunkt tv gilt: d[v] > d(s,v). O.B.d.A. wählen wir v so, dass tv minimal ist. Sei W einen kürzesten s-v-Weg . Wir betrachten den Zeitpunkt tv. Sei y der erste Knoten in W, der zu F gehört (mög. y = v). Sei x der Vorgänger von y in W (mög. x= s). Es gilt d[v] · d[y], weil v als nächstes von F entfernt wird. 32 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen Beweis (Forts.): Darüber hinaus: 1. d[x] = d(s,x). Weil x schon aus F entfernt wurde, und wegen der Minimalität von v. 2. d[y]=d(s,y). Da W minimal ist, gilt d(s,y)=d(s,x)+d(x,y). Als x von F entfernt wurde, wurde ein Update von d[y] durchgeführt, mit dem Ergebnis d[y] · d(s,x)+d(x,y). Damit gilt d[y] · d(s,y), und so d[y]=d(s,y). 3. d(s,y) · d(s,v). Weil W ein kürzester s-v-Weg ist, und W den Knoten y besucht. Aus (1)-(3) folgt: d[y] = d(s,y) · d(s,v) · d[v]. Damit gilt d[y] · d[v], und so d[v]=d[y] und d[v]=d(s, v), in Widerspruch zur Annahme. 33 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Dijkstras Algorithmus Beispiel: 34 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Dijkstras Algorithmus Beispiel: 4 35 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Dijkstras Algorithmus Beispiel: 2 4 36 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Dijkstras Algorithmus Beispiel: 2 4 37 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Dijkstras Algorithmus Beispiel: 2 4 38 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Minimale Spannbäume Beispiel: Eine Firma plant eine Vernetzung seiner 5 Computer-Zentren. Die Leasing-Gebühren für die Verbindung zweier Zentren verursachen Kosten. Welche Verbindungen sollen geleast werden, so dass bei minimalen Kosten alle Zentren miteinander kommunizieren können. Lösung: Wir modellieren das Problem als gewichteten Graphen und konstruieren einen 39 Spannbaum mit minimaler Gewichtsumme. Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Minimale aufspannende Bäume Beispiel: d a 1200 c b e 40 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Minimale aufspannende Bäume Eine Lösung des vorhergehenden Beispiels. d Gewichtsumme: 3600 a 1200 c b e 41 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Minimale Spannbäume Der Algorithmus von Kruskal: Eingabe: zusammenhängender Graph G = (V,E) Gewichtsfunktion w: E R. Ausgabe: Spannbaum (V,ET) mit minimalem Gewicht. Sortiere die Kanten von E nach Gewicht in aufsteigender Reihenfolge; sei L die sortierte Liste. ET à ;; while L ist nicht leer entferne die erste Kante k von L; wenn (V, ET [ {k}) kreisfrei dann ETà ET [ {k} 42 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Der Algorithmus von Kruskal Beispiel: a 2 3 b 3 1 e 4 4 3 1 2 f 3 2 i c j 5 g 3 4 3 d h 3 k 1 l 43 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Iteration Kante Gewicht 1 {c,d} 1 2 {k,l} 1 3 {b,f} 1 4 {c,g} 2 5 {a,b} 2 6 {f,j} 2 7 {b,c} 3 8 {j,k} 3 9 {g,h} 3 10 {i,j} 3 11 {a,e} 3 Kapitel IV – Graphen; Algorithmen • Traversierung von Wurzelbäumen Seien T1, …, TnT die Teilbäume von T von links nach rechts. a Trav(T) b f e k j 44 n c o Ausgabe Wurzel; Trav(T1); … ; Trav(TnT). d g h m l i Ergebnis: a,b,e,j,k,n,o,p,f,c,d,g,l,m,h,i p Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Traversierung von Wurzelbäumen Seien T1, …, TnT die Teilbäume von T von links nach rechts. a Trav(T) b f e k j 45 n c o d g h m l i Trav(T1); Ausgabe Wurzel; Trav(T2); …; Trav(TnT). Ergebnis: j,e,n,k,o,p,b,f,a,c,l,g,m,d,h,i p Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Traversierung von Wurzelbäumen Seien T1, …, TnT die Teilbäume von T von links nach rechts. a Trav(T) b f e k j 46 n c o Trav(T1); … ; Trav(TnT); Ausgabe Wurzel. d g h m l i Ergebnis: j,n,o,p,k,e,f,b,c,l,m,g,h,i,d,a p Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Preorder-Traversierung von Wurzelbäumen Procedure preorder (Eingabe: Wurzelbaum T) v Wurzel von T; Gebe Inhalt von v aus for all u (v) von links nach rechts do // bearbeite alle Kinder begin T Teilbaum von T mit u als Wurzel preorder(T); // rekursiver Aufruf der Traversierung end 47 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Postorder-Traversierung von Wurzelbäumen Procedure postorder (Eingabe: Wurzelbaum T) v Wurzel von T; for all u begin (v) von links nach rechts do // bearbeite alle Kinder T Teilbaum von T mit u als Wurzel postorder(T); // rekursiver Aufruf der Traversierung end Gebe Inhalt von v aus 48 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München Kapitel IV – Graphen; Algorithmen • Inorder-Traversierung von Wurzelbäumen Procedure inorder (Eingabe: Wurzelbaum T) v Wurzel von T; if IsLeaf(v) then Gebe Inhalt von v aus else begin l erstes Kind von v von links nach rechts; T Teilbaum von T mit l als Wurzel; inorder(T); // rekursiver Aufruf der Traversierung Gebe Inhalt von v aus for all u (v) \ { l } von links nach rechts do begin T Teilbaum von T mit u als Wurzel; inorder(T); end end 49 Vorlesung Diskrete Strukturen WS 08/09 Prof. Dr. J. Esparza – Institut für Informatik, TU München