Netzwerk Simplex Algorithmus für Minimum Cost Flow Probleme Jan Burkl 13. Juni 2003 Seminar Universität Trier Sommersemester 2003 Prof. S. Näher, O. Zlotowski 1 Inhaltsverzeichnis 1 Einleitung 3 2 Bezeichnungen und Definitionen 3 3 Spanning Tree Solution 6 4 Beschreibung einer Spanning Tree Structure 10 5 Knotenpotentiale berechnen 12 6 Initialer Spannbaum 14 7 Simplex-Algorithmus 16 7.1 Entering Arc . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 7.1.1 Dantzig’s Pivot Regel . . . . . . . . . . . . . . . . . . . 17 7.1.2 First Eligable Arc Rule . . . . . . . . . . . . . . . . . . 17 7.1.3 Kandidaten-Liste Pivot-Regel . . . . . . . . . . . . . . 18 7.2 Leaving Arc . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 7.3 Spannbaum updaten . . . . . . . . . . . . . . . . . . . . . . . 20 7.4 Beispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 8 Strongly Feasible Spanning Tree 8.1 25 Leaving Arc Rule . . . . . . . . . . . . . . . . . . . . . . . . . 26 2 1 Einleitung Der Simplex-Algorithmus ist einer der mächtigsten Algorithmen zum Lösen von Optimierungsproblemen. Obwohl er nicht direkt für eine Netzwerkstruktur konstruiert wurde, lässt er sich doch einfach modifizieren, um ein Minimum Cost Flow Problem effizient zu lösen. Im einzelnen betrachtet diese Seminararbeit folgende Aspekte: Es wird gezeigt, dass jedes Minimum Cost Flow Problem mindestens eine Spanning Tree Solution besitzt. Diese Spanning Tree Solutions sind die Grundlage der Simplex-Methode, da von einer Lösung zur nächsten gewechselt wird, bis die Optimallösung gefunden ist. Als nächstes wird beschrieben, wie solche Spanning Trees am geschicktesten implementiert werden können, damit der Algorithmus auch effizient ausgeführt werden kann. Bevor dann die eigentliche Simplex-Methode erklärt wird, muss vorher gezeigt werden, wie die sogenannten Knotenpotentiale berechnet werden und ein initialer Spannbaum konstruiert wird. Auch dieser Schritt muss genau durchdacht sein, damit der Netzwerk-Simplex-Algorithmus effizient ausgeführt werden kann. Schließlich wird eine einfache Methode beschrieben, wie der Algorithmus so modifiziert werden kann, dass eine Terminierung bzw. die Finitheit garantiert ist. 2 Bezeichnungen und Definitionen Einige grundlegende Begriffe aus der Graphentheorie werden in dieser Arbeit vorausgesetzt. So betrachten wir ein gerichtetes Netzwerk N mit n Knoten und m gerichteten Kanten. Die Menge der gerichteten Kanten nennen wir E. Auf diesem Netzwerk N können wir ein sogenanntes Minimum Cost Flow Problem beschreiben, dass wir mit Hilfe des Netzwerk Simplex Algorithmus 3 lösen können: Definition 2.1 (Min Cost Flow Problem). Sei N ein gerichtetes Netzwerk. Jede Kante (i, j) ∈ E hat bestimmte Kosten cij , die die Kosten pro Flusseinheit auf dieser Kante beschreiben. Außerdem hat jede Kante (i, j) ∈ E eine obere Kapazitätsschranke uij , das die maximal mögliche Menge von Flusseinheiten auf dieser Kante beschreibt. Mit jedem Knoten i gibt es auch einen ganzzahligen Wert b(i), der das Angebot (b(i) > 0) bzw. die Nachfrage (b(i) < 0) des Knotens angibt. Der Fluss, der über eine Kante (i, j) ∈ E fließt, wird mit xij bezeichnet. Das Min Cost Flow Problem wird jetzt wie folgt definiert: X min cij xij (i,j)∈E s.t. X X xi,j − {j:(i,j)∈E} xji = b(i) ∀i ∈ N (1) 0 ≤ xij ≤ uij (i, j) ∈ E (2) {j:(j,i)∈E} Bemerkung 1. Wir betrachten ausschließlich Netzwerke N, deren Kantenfluss nach unten durch 0 beschränkt ist. Bemerkung 2. Wir sprechen von einem zulässigen Fluss x, wenn die Bedingungen (1) und (2) für alle xij ((i, j) ∈ E) erfüllt sind. Um aus dem zulässigen Fluss einen optimalen zulässigen Fluss zu berechnen, benötigt der Simplex Algorithmus den Spanning Tree. 4 Definition 2.2. Ein zusammenhängender Graph ohne Kreis ist ein Spanning Tree T von N , wenn alle Knoten aus N auch in T enthalten sind. Ein Spanning Tree T von N mit zulässigem Fluss entspricht einer Basislösung des Simplex Algorithmus. Weiterhin benötigen wir die reduzierten Kosten aller Kanten: Definition 2.3. cπij bezeichnet die reduzierten Kosten einer Kante (i, j) ∈ E wenn gilt: cπij = cij − π(i) + π(j), wobei π(i) das Knotenpotential des Knotens i ist (Das Knotenpotential eines Knotens i entspricht in einem Spanning Tree dem negativen Distanzwert von der Wurzel zum Knoten i). Da wir im Simplex Algorithmus mit den reduzierten Kosten arbeiten, ist es wichtig den Zusammenhang zwischen den Funktionswerten z(π) := X cπij xij (i,j)∈E und z(0) := X cij xij (i,j)∈E zu verstehen. Sei zu Beginn π(0). Wir erhöhen jetzt das Knotenpotential von Knoten k zu π(k). Dadurch werden die reduzierten Kosten jeder ausgehenden Kante von k verringert, während die reduzierten Kosten der eingehenden Kanten um π(k) erhöht werden. Somit ändert sich der Zielfunktionswert um π(k)-mal dem ausgehenden Fluss minus π(k)-mal dem eingehenden Fluss von k. Da 5 der ausgehende Fluss gleich dem eingehenden Fluss sein muss (Massenbalance), reduziert eine Erhöhung des Potentials von Knoten k um π(k) den Zielfunktionswert um π(k)b(k). Wiederholt man dies für alle Knoten, erhält man z(0) − z(π) = X π(i)b(i). i∈N Für ein gegebenes π ist das Ergebnis konstant und somit gilt min z(π) ≡ min z(0). 3 Spanning Tree Solution Definition 3.1. Sei x eine zulässige Lösung für ein Netzwerk N, dann heißt eine Kante (i, j) • frei, wenn 0 < xij < uij , • beschränkt, wenn xij = 0 oder xij = uij , wobei xij der Fluss der Kante (i, j) ist und uij die obere Flussgrenze der Kante (i, j). Der Einfachheit halber ist die untere Flussgrenze gleich 0. Bemerkung 3. Auf beschränkten Kanten kann man den Fluss nur verringern (xij = uij ) oder nur erhöhen (xij = 0). Definition 3.2. • Eine Lösung eines Netzwerks N heißt Cycle Free Solution, wenn sie keinen Kreis enthält, der nur aus freien Kanten besteht. 6 • Eine Lösung heißt Spanning Tree Solution, wenn (zu einem Spanning Tree aus dem gegebenen Netzwerk) jede nicht-Baum-Kante eine beschränkte Kante ist. Bemerkung 4. Jede Spanning Tree Solution ist eine Cycle Free Solution. Umgekehrt gilt dies nicht. Eine Cycle Free Solution erhalten wir in der Simplex-Methode immer, wenn wir den Fluss des Kreises, der durch Einfügen einer Kante in den Spannbaum entstanden ist, maximal erhöht haben (Kapitel 7.2). Diese Cycle Free Solution können wir dann ganz einfach wieder zu einer Spanning Tree Solution umbauen. Betrachtet man nur die freien Kanten einer Cycle Free Solution, so erhält man einen Wald mit k Bäumen (im Spezialfall k = 1 direkt einen Spanning Tree), da nach Definition 3.2 jeder ursprüngliche Kreis mindestens eine beschränkte Kante enthält. Wenn man jetzt mit k − 1 beschränkten Kanten alle k entstandenen Bäume zusammenfügt, erhält man eine Spanning-Tree-Solution. Beispiel 3.1. Wir können an Beispiel aus Abbildung 3.1 erkennen, dass es möglich ist aus einer Cycle Free Solution verschiedene Spanning Tree Solutions zu gewinnen. Denkbar wäre auch eine Lösung mit den Kanten (1, 3), (3, 2), (3, 4). Eine Spanning Tree Solution teilt die Menge der Kanten des Netzwerks in drei Gruppen auf: T: Alle Kanten im Spanning Tree L: Alle nicht-Baum-Kanten mit xij = 0 U: Alle nicht-Baum-Kanten mit xij = uij 7 (a) Beispiel-Netzwerk (b) Alle freien Kanten (c) Zwei mögliche Spanning Tree Solution Abbildung 1: Konstruktion von Spanning Tree Solution aus einer Cycle Free Solution Wir nennen das Tupel (T,L,U) Spanning Tree Structure. Eine Spanning Tree Structure heißt zulässig, wenn die zugehörige Spanning Tree Solution die Kapazitätsschranken der Kanten erfüllt. Bemerkung 5. Wenn jede Baumkante eine freie Kante ist, so nennt man den Spanning Tree nichtdegenerativ, andernfalls degenerativ. Essentiell für die Durchführung des Simplex-Algorithmus ist der folgende Satz. Dabei betrachten wir die reduzierten Kosten cπij = cij − π(i) + π(i), die wir in der Simplex-Methode als Optimalitätskriterium nutzen. 8 Satz 3.1 (Min-Cost-Flow Optimalitätsbedingungen). Eine Spanning Tree Structure (T,L,U) ist ein optimale Spanning Tree Structure, wenn die Lösung zulässig ist und (für eine Wahl des Knotenpotentials π) die reduzierten Kosten cπij folgende Bedingungen erfüllen: a) cπij = 0, ∀(i, j) ∈ T b) cπij ≥ 0, ∀(i, j) ∈ L c) cπij ≤ 0, ∀(i, j) ∈ U Beweis. Sei x∗ die zur Spanning Tree Solution (T,L,U) zugehörige Lösung. Wir wissen, dass für ein bestimmtes π die Bedingungen erfüllt sind. Wir müssen jetzt zeigen, dass x∗ eine optimale Lösung des Min-Cost-Flow Problems ist. Da cπij = cij − π(i) + π(j) gilt nach Kapitel 2 min( X cij xij ) ≡ min( (i,j)∈A X cπij xij ) (i,j)∈A Für ein gegebenes π gilt weiter: X min( cπij xij ) (i,j)∈A X X P π π π cij xij ≡ min cij xij + (i,j)∈L cij xij + |{z} (i,j)∈T (i,j)∈U | {z } ≤0 | {z } =0 ≡ min ≤0 P π (i,j)∈L cij xij 9 − π (i,j)∈U |cij |xij P (3) Da für eine beliebige Lösung x xij ≥ x∗ij ∀(i, j) ∈ L und xij ≤ x∗ij ∀(i, j) ∈ U gilt, kann (3) mit der Lösung x nur größer oder gleich des Zielfunktionswertes der Lösung x∗ werden. Bemerkung 6. Eine Spanning Tree Structure ist optimal, wenn die zugehörige Spanning Tree Solution eine Optimallösung des Min-Cost-Flow Problems ist. 4 Beschreibung einer Spanning Tree Structure Damit der Simplex-Algorithmus effektiv arbeiten kann, muss der Spanning Tree geeignet im Computer dargestellt werden. Wir stellen uns den Spanning Tree wie folgt vor: Von einer Wurzel (root) hängt der Baum nach unten. Um diese Struktur darstellen zu können, brauchen wir drei Indizes: Definition 4.1. • Der Predecessor Index pred(i) bezeichnet den Knoten j, der auf dem eindeutigen Pfad von i zur Wurzel liegt, wenn die Kante (i,j) existiert. D.h. pred(i)=j ist der direkte Vorgänger von i auf dem Weg von i zur Wurzel. • Der Depth Index depth(i) bezeichnet die Anzahl der Kanten des eindeutigen Pfades von i zur Wurzel, d.h. die Tiefe des Knotens in dem hängenden Baum, wobei die Wurzel Tiefe 0 hat. 10 i 1 2 3 4 5 6 7 8 9 10 11 pred(i) 0 1 1 2 3 3 4 4 6 8 8 depth(i) 0 1 1 2 2 2 3 3 3 4 4 thread(i) 2 4 6 7 3 9 8 10 1 11 5 Abbildung 2: Beispiel eines Netzwerks mit dazugehörigen Baumindizes • Der Thread Index thread(i) bezeichnet den direkten Nachfolger j des Knotens i bei der vollständigen Traversierung des Baumes. Die Thread Indizes definieren somit einen Weg von der Wurzel über alle Knoten zurück zur Wurzel. Diese Thread Indizes sind nicht eindeutig bestimmt. Je nach Anwendung kann man sie z.B. durch einen Preorder Traversal erreichen. Beispiel 4.1. Knoten 1 ist die Wurzel. Die gestrichelten Kanten in Abb. 2 entsprechen dem Traversierungspfad des Netzwerks. 11 5 Knotenpotentiale berechnen Um die im vorigen Kapitel erwähnten reduzierten Kosten ermitteln zu können, müssen vorher die Potentiale aller Knoten berechnet werden. Dafür können wir das Knotenpotential des Wurzelknotens beliebig setzen (hier gleich 0) und können so alle anderen Potentiale berechnen. Lemma 5.1. Das Knotenpotential des Wurzelknotens kann π(1) = 0 gesetzt werden, ohne dass diese Änderung Auswirkung auf die reduzierten Kosten aller Kanten hat. Beweis. Addition einer Konstanten k bewirkt keine Änderung der reduzierten Kosten, da cπij = cij − π(i) + π(j) = cij − [π(i) + k] + [π(j) + k]. Wir nutzen jetzt die Eigenschaft aus, dass gilt: cπij = cij − π(i) + π(j) = 0 ∀(i, j) ∈ T (4) Somit können wir, wenn ein Knotenpotential der Gleichung 4 bekannt ist, das Potential des anderen Knotens berechnen. Dabei starten wir mit dem Wurzelknoten i = 1, da nach Lemma 5.1 π(1) = π(i) = 0 bekannt ist und berechnen sukzessive anhand der Thread Indizes und des folgenden Algorithmus alle Knotenpotentiale. Algorithmus 1. 12 procedure compute-potentials; begin π(1) := 0; j := thread(1); while j 6= 1 do begin i := pred(j); if (i, j) ∈ N then π(j) := π(i) − cij ; if (j, i) ∈ N then π(j) := π(i) + cij ; j := thread(j); end; end; Laufzeitanalyse: Die Prozedur braucht O(1) Zeit für einen Iterationsdurchlauf, der n − 1-mal durchgeführt wird. Somit hat die Prozedur eine Gesamtlaufzeit von O(n). Beispiel 5.1. Wir verwenden den zweiten Spanning Tree aus Beispiel 3.1 c): π(1) = 0 pred(2) = 1 ⇒ π(2) = π(1) − c12 = −5 pred(3) = 1 ⇒ π(3) = π(1) − c13 = −3 pred(4) = 2 ⇒ π(4) = π(2) − c24 = −5 − 2 = −7 An diesem Beispiel kann man erkennen, dass die Knotenpotentiale nichts anderes als die negativen Distanzwerte vom Wurzelknoten aus darstellen. 13 6 Initialer Spannbaum Damit der Simplex Algorithmus auf jedes beliebige Netzwerk N angewendet werden kann, muss zunächst ein initialer Spannbaum mit gültigem Fluss aus N konstruiert werden. Der initiale Spannbaum entspricht einer gültigen Startlösung. Um eine solche Startlösung zu erreichen, fügt man einen neuen, künstlichen Knoten r ein und n (Anzahl der Knoten in N ) neue, künstliche Kanten, die wie folgt konstruiert werden: Wir untersuchen jeden Knoten j aus N . Wenn b(j) > 0, fügen wir eine Kante (j, r) ein, mit einem Fluss von b(j). Ist b(j) ≤ 0, so fügen wir eine Kante (r, j) mit Fluss von −b(j) ein. Alle Kanten haben unendlich grosse Kapazität, ebenso setzt man ihre Kosten sehr hoch, damit es auf jeden Fall teurer ist, wenn Fluss über künstliche Kanten fließt. Die Kosten der künstlichen Kanten können sich z.B. wie folgt ergeben: crk = ckr = X cij + 1 ∀k ∈ N. (i,j)∈N Alle anderen Kanten haben zu diesem Zeitpunkt noch keinen Fluss. Wir erhalten so einen Spanning Tree aus dem Orginalnetzwerk mit Wurzel r und ausschließlich künstlichen Kanten zu allen Knoten aus N mit zulässigem 14 Fluss, wobei die Flusseinheiten zu diesem Zeitpunkt nur von den Senken über den Knoten r zu den Quellen fließt. Beispiel 6.1. Wir nutzen das Netzwerk N aus Bsp. 3.1. Abb. 3(a) zeigt das ursprüngliche Netzwerk, in Abb. 3(b) sieht man den konstruierten Spanning Tree mit künstlichem Wurzelknoten und künstlichen Kanten. In diesem Beispiel entspricht Knoten 1 der Quelle s, Knoten 2 der Senke t und der neue, künstliche Knoten r ist Knoten 5. (a) Beispiel-Netzwerk (b) Konstruierter Spanning Tree Abbildung 3: Initialer Spannbaum Existiert eine Lösung für das gegebene Problem, dann berechnet der Simplex Algorithmus einen Fluss x, bei dem nur Kanten des Orginalnetzwerks positive Flusswerte haben. Daher setzt man die Kosten der künstlichen Kanten so hoch, dass es auf jeden Fall günstiger ist, Fluss über die Kanten des gegebenen Netzwerks fließen zu lassen, wenn das Problem lösbar ist. 15 7 Simplex-Algorithmus Sei (T, L, U ) eine mögliche Spanning Tree Struktur des Min-Cost-Flow-Problems und π die entsprechenden Knotenpotentiale. Nach Satz 3.1 ist diese Lösung optimal, wenn gilt: ∀(i, j) ∈ L : cπij ≥ 0, ∀(i, j) ∈ U : cπij ≤ 0. Sollten die Bedingungen nicht erfüllt sein, so muss eine Kante durch eine andere ersetzt werden, damit der Zielfunktionswert in Richtung des optimalen Werts verbessert wird. Dadurch ändern sich bestimmte Knotenpotentiale, sowie reduzierte Kosten einzelner Kanten. Diese müssen angepasst werden und die Optimalitätsbedingungen erneut überprüft werden. Im einzelnen lautet der Simplex -Algorithmus wie folgt: Algorithmus 2. algorithm network simplex begin konstruiere initialen Spannbaum; solange die Optimalitätsbedingungen nicht erfüllt sind tue wähle eine einzufügende Kante, die die Optimalitätsbedingung verletzt; füge diese Kante ein und bestimme die wegfallende Kante; baue den Spannbaum neu auf und passe x und π an; end; end; Bemerkung 7. Sollte noch Fluss auf den eingefügten künstlichen Kanten fließen, obwohl alle 16 Optimalitätskriterien erfüllt sind, so gibt es keine zulässige Lösung für dieses Netzwerk. 7.1 Entering Arc Die einzufügende Kante muss aus der Menge der Kanten stammen, die die obigen Optimalitätsbedingungen nicht erfüllen (sie kann also nur aus L oder U stammen). Für die Wahl dieser Kante gibt es verschiedene Pivotregeln, drei werden an dieser Stelle vorgestellt. 7.1.1 Dantzig’s Pivot Regel Die Regel wählt in jeder Iteration die Kante mit der höchsten Verletzung. (Als Verletzung einer Kante (i, j) bezeichnen wir |cπij |). Der Hintergrund zu dieser Regel ist die größere Verringerung des Zielfunktionswertes bei einer hohen Verletzung, wenn alle Kandidaten eine ähnlich hohe Flussänderung bewirken. Der Algorithmus muss also alle Kanten aus L und U nach der maximalen Verletzung durchsuchen. Da dies jedoch bei jeder Iteration gemacht werden muss, ist diese Regel auf Grund der hohen Laufzeit für die Praxis nicht geeignet. 7.1.2 First Eligable Arc Rule Bei dieser Regel werden alle Kanten durchsucht und die erste geeignete Kante ausgewählt. Eine bekannte Variante dieser Regel arbeitet nach der ’wraparound fashion’. Dabei wird die letzte gewählte Kante als Startpunkt für die neue Suche gesetzt. Durch diese Tatsache wird schnell die neue, einzufügende Kante gefunden. Diese hat aber in den meisten Fällen nur eine geringe Verletzung und somit eine kleine Reduzierung des Zielfunktionswertes. Durch 17 die vielen daraus resultierenden Iterationen ist auch diese Regel nicht für die Praxis geeignet. 7.1.3 Kandidaten-Liste Pivot-Regel Dieser Algorithmus ist eine Zwei-Phasen-Prozedur, bestehend aus einer Hauptiteration und einer Nebeniteration. In der Hauptiteration werden ausgehend von der Wurzel alle geeigneten Kanten in eine Kandidatenliste eingefügt. Das wiederholt man für Knoten 2, 3, ..., bis entweder alle geeigneten Kanten eingefügt sind oder der für die Liste allokierte Speicherplatz belegt ist. Die nächste Hauptiteration beginnt an dem Knoten, an dem die vorhergehende Iteration endete. In der Nebeniteration wird die Liste nach der Kante mit der maximalen Verletzung durchsucht. Gleichzeitig werden alle nicht mehr geeigneten Kanten wieder aus der Liste entfernt. Das wiederholt sich solange, bis die Liste leer ist oder die angegebene maximale Anzahl der Iterationsdurchläufe erreicht ist. Anschließend wird eine neue Liste in der Hauptiteration aufgebaut. Man kann erkennen, dass diese Regel viele Möglichkeiten zur Optimierung bietet und sowohl die Dantzig’s Pivot Regel als auch die First Eligable Arc Rule Spezialfälle der Kandidaten-Liste Pivot-Regel sind(Größe der Kandidatenliste = 1 ⇒ First Eligable Arc Rule; Größe der Kandidatenliste = ∞ ⇒ Dantzig‘s Pivot Regel). In der Praxis hat sich diese Mischung aus den beiden anderen Pivotregeln auf Grund ihrer schnelleren Laufzeit bewährt. 7.2 Leaving Arc Nachdem eine Kante eingefügt wurde, muss auch wieder eine entfernt werden, damit die Spanning Tree Struktur wieder aufgebaut werden kann. Sei (k, l) die eingefügte Kante. (k, l) erzeugt genau einen Kreis W (Pivot18 Kreis), dessen Orientierung der Richtung von (k, l) entspricht, wenn (k, l) ∈ L und entgegengesetzt, wenn (k, l) ∈ U . So wird der Kreis W partitioniert in W und W . Dabei enthält W alle Vorwärtskanten (entsprechend der Orientierung des Pivot-Kreises), W alle Rückwärtskanten. Wir erhöhen den Fluss (entlang W ) jetzt um δ = min (δij | (i, j) ∈ W ) , wobei u − x , wenn (i, j) ∈ W ij ij . δij = x , wenn (i, j) ∈ W ij So erreicht mindestens eine Kante ihre obere bzw. untere Grenze. Diese Kante (i, j) bzw. eine dieser Kanten (kann beliebig gewählt werden) heißt blockierende Kante. Diese wird aus T entfernt und in L eingefügt (wenn xij = 0) oder in U eingefügt (wenn xij = uij ). Bemerkung 8. Ein positiver erhöhender Fluss entlang W erhöht den Fluss auf Vorwärtskanten, verringert ihn auf Rückwärtskanten. Definition 7.1. Eine Pivot-Operation heißt • nichtdegenerative Iteration, wenn δ > 0, • degenerative Iteration, wenn δ = 0. Bemerkung 9. Wenn es mehr als eine Kante gibt, die durch den erhöhenden Fluss an ihre Grenzen stoßen, so wird der nächste Spanning Tree degenerativ sein. 19 Die Schwierigkeit bei diesem Verfahren liegt in der Erkennung des Kreises. Effizient lösen kann man dieses Problem, wenn man den Spanning Tree vor Einfügen der neuen Kante (k, l) betrachtet. Jetzt werden in einer Schleife die Vorgänger von k und l solange aufgerufen, bis der gemeinsame Vorgänger gefunden ist. Das konkrete Vorgehen beschreibt der nachfolgende Algorithmus: Algorithmus 3. procedure identify-cycle; begin i:=k und j:=l; while i 6= j do begin if depth(i) > depth(j) then i:=pred(i); else if depth(j) > depth(i) then j:=pred(j); else i:=pred(i) und j:=pred(j); end; end; 7.3 Spannbaum updaten Wenn die wegfallende Kante (p, q) gleich der eingefügten Kante (k, l) ist (δ = δkl = ukl ), ändert sich T nicht, lediglich die Kante (k, l) wechselt von L nach U oder umgekehrt. Ist (p, q) ungleich (k, l), so müssen einige Veränderungen vorgenommen werden. Als erstes wird (p, q) zu L hinzugefügt (wenn xpq = 0), bzw. zu U (wenn xpq = upq ) hinzugefügt. Betrachten wir jetzt den Spannbaum ohne die Kanten (p, q) und (k, l), so erhalten wir einen Teilbaum 20 T1 , der die Wurzel und entweder k oder l enthält. Der zweite Teilbaum T2 hängt dagegen entweder am Knoten p oder q. Der entsprechend andere Knoten befindet sich in T1 . Damit auch im neuen Spannbaum die Bedingung cπij = 0 gilt, müssen die Knotenpotentiale in T1 oder in T2 geändert werden: Wenn k ∈ T1 , dann müssen alle Knotenpotentiale um cπkl verringert werden, wenn k ∈ T2 , dann müssen alle Knotenpotentiale um cπkl erhöht werden. Eine genaue Beschreibung des Spannbaum-Updates liefert der folgende Algorithmus. Algorithmus 4. procedure update-potentials; begin if q ∈ T2 then y := q else y := p; if k ∈ T1 then change := −cπkl else change := cπkl ; π(y) := π(y) + change; z:=thread(y); while depth(z) > depth(y) do begin π(z) := π(z) + change; z:=thread(z); end; end; 7.4 Beispiel Wir nutzen erneut das bekannte Beispiel. Diesmal ist es das vollständige Netzwerk mit Kantenkosten, Kantenbeschränkungen und Supply/Demand. 21 Als erstes wird der künstliche Knoten (5) eingefügt, inkl. aller künstlichen Kanten. Wir lassen 4 Einheiten Fluss über die Kanten (1,5) und (5,4) fließen und berechnen die Knotenpotentiale, wobei wir die Kosten der künstlichen P Kanten mit (i,j)∈N cij + 1 = 16 Einheiten veranschlagen. Mit dieser Berechnung der Kantenkosten ist bei allen Min-Cost-Flow Problemen sichergestellt, dass es auf jeden Fall teurer ist, Fluss über die künstlichen Kanten fließen zu lassen. Somit haben wir den initialen Spannbaum (durchgezogene Kanten). Da die Kante (1,3) die höchsten reduzierten Kosten besitzt (cπ13 = −29), wählen wir diese als einzufügende Kante(grün). Weil δ jedoch 0 ist, kann der Fluss nicht erhöht werden. Wir wählen daraufhin (5,3) als blockierende Kante(rot), und entfernen diese aus dem Spannbaum, und fügen sie in die Menge L ein. 22 Das Knotenpotential von Knoten 3(rot) inkl. der reduzierten Kosten aller inzidenten Kanten muss jetzt erneuert werden, woraufhin Kante (3,2) mit cπ32 = −28 als neue Baumkante gewählt wird. Wiederum kann der Fluss nicht erhöht werden, so wird Kante (5,2) nach L verschoben. Nach einigen weiteren Schritten erhalten wir das linke unten stehende Bild. 23 Bis hierhin sind auch Kanten (1,3) und (2,4) aus dem Baum nach U verschoben worden. Beide Kanten sind mit maximalem Fluss (x13 = x24 = 3) entfernt worden. Ein Update müssen hier die Knoten 2 und 3 erhalten. Kante (1,2) wird neu eingefügt und der Fluss kann um eine Einheit erhöht werden. Kante (5,4) muss daraufhin entfernt werden. Nach einem Update der Knoten 2,3 und 4 sind alle Optimalitätsbedingungen erfüllt. Da Optimalitätsbedingungen auf allen Kanten erfüllt ist und kein Fluss auf künstlichen Kanten fließt, ist die Lösung optimal mit Flusskosten von 26 Einheiten. 24 8 Strongly Feasible Spanning Tree Es kann passieren, dass die Simplex-Methode nicht terminiert. Damit der Algorithmus nicht in eine Endlosschleife gerät, wird hier das Konzept des Strongly Feasible Spanning Tree mit einer Leaving Arc Rule vorgestellt, die die Finitheit des Algorithmus garantiert. Stellen wir uns nochmal den Spanning Tree (T, L, U ) als hängenden Baum vor, dann gibt es Kanten, die nach oben zeigen (upward pointing) oder die nach unten zeigen (downward pointing). Definition 8.1. Ein Spannbaum T ist strongly feasible, wenn jede Baumkante ohne Fluss nach oben zeigt und jede Baumkante deren Fluss gleich ihrer Kapazität ist nach unten zeigt. Definition 8.2. 25 Ein Spannbaum ist strongly feasible, wenn es möglich ist, einen Fluss von einem beliebigem Knoten zur Wurzel zu schicken, ohne Kapazitätsgrenzen zu verletzen. Bemerkung 10. Man kann leicht zeigen, dass diese beiden Definitionen äquivalent sind. Leider erhalten wir durch Konstruktion des initialen Spannbaums keinen Strongly Feasible Spanning Tree. Dies kann jedoch erreicht werden, wenn die Definition für eine Startlösung wie folgt geändert wird: Wir untersuchen jeden Knoten j aus N (Orginalnetzwerk). Wenn b(j) ≥ 0(statt b(j > 0)) , fügen wir eine Kante (j, r) (mit r als neuem künstlichem Knoten) ein, mit einem Fluss von b(j). Ist b(j) < 0(statt b(j) ≤ 0), so fügen wir eine Kante (r, j) mit Fluss von −b(j) ein. Jetzt ist leicht zu sehen, dass es möglich ist von jedem Knoten Fluss zur Wurzel r zu schicken. Da wir durch unsere Konstruktion des initialen Spannbaums immer einen nicht-degenerativen Baum erhalten, haben wir auch automatisch zu Beginn einen Strongly Feasible Spanning Tree. Jetzt gilt es, diese Eigenschaft im Spanning Tree beizubehalten. Der Spannbaum kann im nächsten Schritt nur degenerieren, wenn es mehr als eine blockierende Kante gibt, d.h. ist die blockierende Kante eindeutig, so erhält man auch im nächsten Schritt einen Strongly Feasible Spanning Tree. Damit dies auch im anderen Fall passiert, gibt es folgende Regel. 8.1 Leaving Arc Rule Aus dem Spannbaum soll die letzte blockierende Kante, die nach Traversierung (entlang der Orientierung der eingefügten Kante) des entstanden Krei26 ses entfernt werden. Dabei wird am Knoten w, der höchste Punkt (apex) des Kreises im hängenden Baum, gestartet. Durch diese Regel wird der Kreis W in W1 und W2 geteilt. W1 ist der Teil von W vom Knoten w bis zur Kante (p, q) (entfernte Kante), W2 = W − W1 − {(p, q)}. Beide Teile haben die gleiche Orientierung wie der Kreis W . Satz 8.1. a) Jeder Knoten im Segment W2 kann einen positiven Fluss zur Wurzel schicken. b) Jeder Knoten im Segment W1 kann einen positiven Fluss zur Wurzel schicken. Beweis. a) Da (p, q) die letzte blockierende Kante war, kann in W2 keine blockierende Kante sein. Deshalb ist es auf jeden Fall möglich, dass jeder Knoten aus W2 noch Fluss zur Wurzel schicken kann. b) Fall 1: Wenn die vorhergende Pivotoperation den Fluss entlang W1 erhöht hat und damit eine nichtdegenerative Pivotoperation war, dann kann im nächsten Schritt der Fluss auch wieder in die andere Richtung (zur Wurzel hin) geschickt werden. Fall 2: Wenn in der vergangenen Pivotoperation keine Flusserhöhung durchgeführt wurde, muss W1 zwischen w und k liegen, da nach den Eigenschaft des Strongly Feasible Trees Fluss von l zur Wurzel geschickt werden kann. Und da der 27 Fluss ja auch nicht im Segment W1 erhöht wurde, kann auch positiver Fluss von jedem Knoten in W1 zur Wurzel geschickt werden. Die Finitheit resultiert jetzt daraus, dass mit jeder Flusserhöhung in den Pivotoperationen der Zielfunktionswert vermindert wird. Das kann aber nur endlich oft passieren, deswegen garantiert diese Methode die Finitheit des Algorithmus. Beispiel 8.1. Abbildung 4: Strongly Feasible Spanning Tree 28 Literatur [1] Ravindra K. Ahuja, James B. Orlin, Thomas L. Magnanti, Network Flows: Theory, Algorithms & Applications, Prentice Hall, 1993. 29