matheraum.de
Raum für Mathematik
Offene Informations- und Nachhilfegemeinschaft

Für Schüler, Studenten, Lehrer, Mathematik-Interessierte.
Hallo Gast!einloggen | registrieren ]
Startseite · Forum · Wissen · Kurse · Mitglieder · Team · Impressum
Forenbaum
^ Forenbaum
Status Hochschulmathe
  Status Uni-Analysis
    Status Reelle Analysis
    Status UKomplx
    Status Uni-Kompl. Analysis
    Status Differentialgl.
    Status Maß/Integrat-Theorie
    Status Funktionalanalysis
    Status Transformationen
    Status UAnaSon
  Status Uni-Lin. Algebra
    Status Abbildungen
    Status ULinAGS
    Status Matrizen
    Status Determinanten
    Status Eigenwerte
    Status Skalarprodukte
    Status Moduln/Vektorraum
    Status Sonstiges
  Status Algebra+Zahlentheo.
    Status Algebra
    Status Zahlentheorie
  Status Diskrete Mathematik
    Status Diskrete Optimierung
    Status Graphentheorie
    Status Operations Research
    Status Relationen
  Status Fachdidaktik
  Status Finanz+Versicherung
    Status Uni-Finanzmathematik
    Status Uni-Versicherungsmat
  Status Logik+Mengenlehre
    Status Logik
    Status Mengenlehre
  Status Numerik
    Status Lin. Gleich.-systeme
    Status Nichtlineare Gleich.
    Status Interpol.+Approx.
    Status Integr.+Differenz.
    Status Eigenwertprobleme
    Status DGL
  Status Uni-Stochastik
    Status Kombinatorik
    Status math. Statistik
    Status Statistik (Anwend.)
    Status stoch. Analysis
    Status stoch. Prozesse
    Status Wahrscheinlichkeitstheorie
  Status Topologie+Geometrie
  Status Uni-Sonstiges

Gezeigt werden alle Foren bis zur Tiefe 2

Navigation
 Startseite...
 Neuerdings beta neu
 Forum...
 vorwissen...
 vorkurse...
 Werkzeuge...
 Nachhilfevermittlung beta...
 Online-Spiele beta
 Suchen
 Verein...
 Impressum
Das Projekt
Server und Internetanbindung werden durch Spenden finanziert.
Organisiert wird das Projekt von unserem Koordinatorenteam.
Hunderte Mitglieder helfen ehrenamtlich in unseren moderierten Foren.
Anbieter der Seite ist der gemeinnützige Verein "Vorhilfe.de e.V.".
Partnerseiten
Weitere Fächer:

Open Source FunktionenplotterFunkyPlot: Kostenloser und quelloffener Funktionenplotter für Linux und andere Betriebssysteme
StartseiteMatheForenOperations ResearchMaxFlowLabeling/FordFulkerson
Foren für weitere Schulfächer findest Du auf www.vorhilfe.de z.B. Geschichte • Erdkunde • Sozialwissenschaften • Politik/Wirtschaft
Forum "Operations Research" - MaxFlowLabeling/FordFulkerson
MaxFlowLabeling/FordFulkerson < Operations Research < Diskrete Mathematik < Hochschule < Mathe < Vorhilfe
Ansicht: [ geschachtelt ] | ^ Forum "Operations Research"  | ^^ Alle Foren  | ^ Forenbaum  | Materialien

MaxFlowLabeling/FordFulkerson: Unklarheiten im Algorithmus
Status: (Frage) beantwortet Status 
Datum: 21:37 Mi 12.08.2009
Autor: Marcel

Eingabefehler: "{" und "}" müssen immer paarweise auftreten, es wurde aber ein Teil ohne Entsprechung gefunden (siehe rote Markierung)
Eingabefehler: "{" und "}" müssen immer paarweise auftreten, es wurde aber ein Teil ohne Entsprechung gefunden (siehe rote Markierung)
Eingabefehler: "{" und "}" müssen immer paarweise auftreten, es wurde aber ein Teil ohne Entsprechung gefunden (siehe rote Markierung)

Hallo,

wie bereits aus dem Threadtitel ersichtlich habe ich bei dem Algorithmus ein paar Verständnisschwierigkeiten. Generell ist mir das Prinzip des Algorithmus klar: Man sucht nach erhöhenden Pfaden, indem man alle Knoten, die über Kanten, auf denen man den Fluss erhöhen kann, labeled, und wenn der Zielknoten gelabeled wird, existiert ein solcher Pfad. Dieser wird mitberechnet und man erhöht den Fluss entlang dieses Pfades.

Im Algorithmus selbst habe ich aber an (wenigstens) zwei Stellen Verständnisschwierigkeiten. Auch selbst gebastelte Beispiele, um zu testen, was da warum passiert, ließen mich bisher leider nicht schlauer werden. Daher hier mal der mir zugrundeliegende Quellcode (mit LEDA; wenn etwas unklar ist, bitte nachfragen):

void MaxFlowLabeling(const graph & G, node s, node t, const edge_array<int> & cap, edge_array <int> & flow)$\{$
  node_array<bool> labeld(G,false);
  node_array<edge> pred(G,NULL);
  while (true) $\{$
    node v;
    forall_nodes(v,G)$\{$
      labeled[v]=false;
      pred[v]=NULL;
    $\}$
    labeled[s]=true;
    L.append[s];
    
    while(! L.empty()) $\{$
      node v=L.pop();
      edge e;
      
        forall_out_edges(e,v) $\{$
        if (flow[e]==cap[e]) continue;
        node w=G.target(e);
        if (labeled[w]) continue;
        labeled[w]=true;
        pred[w]=e;
        L.append(w);
      $\}$
      // $(\star_1)$ Die folgende Forall-Schleife ist mir unklar!!
      forall_in_edges(e,v) $\{$
        if (flow[e]==0) continue;
        node w=G.source(e);
        if (labeled[w]==true) continue;
        labeled[w]=true;
        pred[w]=e;
        // $(\star_2)$ Wieso wird hier $e\,$ als Vorgängerkante von $w\,$ definiert?
        L.append(w);
      $\}$

      if (labeled[t]Eingabefehler: "{" und "}" müssen immer paarweise auftreten, es wurde aber ein Teil ohne Entsprechung gefunden (siehe rote Markierung)
Eingabefehler: "{" und "}" müssen immer paarweise auftreten, es wurde aber ein Teil ohne Entsprechung gefunden (siehe rote Markierung)

)
        AUGMENT(G,s,t,cap,flow,pred)
      else
        break;
  $\}$
$\}$    

void AUGMENT(const graph & G,node s, node t, const edge_array<int> & cap,edge_array<int> & flow, const node_array<edge> & pred)$\{$
  int delta=MAXINT;
  node v=t;
  
  while(v!=s)$\{$
    edge e=pred[v];
    int r;
    if (v==G.target(e))$\{$
      r=cap[e]-flow[e];
      v=G.source(e);
    $\}$
    else $\{$
      r=flow[e];
      v=G.target(e);
    $\}$
    if (r < delta)
      delta=r;
  $\}$
  
  v=t;
  while(v!=s) $\{$
    edge(e)=pred[v];
    if (v==G.target[e]) $\{$
      flow[e]+=delta;
      v=G.source(e);
    $\}$
    else $\{$ //$(\star_3)$ Was geschieht hier nun genau?
      flow[e]-=delta;
      v=G.target(e);
    $\}$
  $\}$
$\}$

Wichtig wäre mir, zu wissen, was genau in $(\star_1)$ passiert (vielleicht klärt sich dann Frage $(\star_2)$ auch mit) bzw. welchen Sinn diese Schleife. Vielleicht klärt sich dann auch die Unklahrheit $(\star_3)$ automatisch mit?!

Ich weiß, es ist sehr aufwendig, aber vll. kennt ja auch jemand ein Beispiel, an dem man der Sinn der Forall-Schleife von $(\star_1)$ deutlich wird? Vielleicht hat sich dort auch irgendwo ein kleiner Fehler eingeschlichen?

Vielen Dank schonmal an alle, die sich alleine die Mühe machen, diesen Algorithmus ein wenig genauer zu betrachten. :-)

Gruß,
Marcel

        
Bezug
MaxFlowLabeling/FordFulkerson: Mitteilung
Status: (Mitteilung) Reaktion unnötig Status 
Datum: 23:50 Mi 12.08.2009
Autor: Karl_Pech

Hallo Marcel,


Ich mußte mich mal vor Urzeiten mit dem Ford-Fulkerson-Algorithmus beschäftigen: read?i=90810. Hilft dir das irgendwie?



Grüße
Karl




Bezug
                
Bezug
MaxFlowLabeling/FordFulkerson: Mitteilung
Status: (Mitteilung) Reaktion unnötig Status 
Datum: 00:06 Do 13.08.2009
Autor: Marcel

Hallo Karl,

> Hallo Marcel,
>  
>
> Ich mußte mich mal vor Urzeiten mit dem
> Ford-Fulkerson-Algorithmus beschäftigen: read?i=90810.
> Hilft dir das irgendwie?

leider nicht wirklich. Generell ist mir das Prinzip ja klar. Mir geht es nur konkret um die Vorgehensweise des Labelings, welches oben praktiziert wird. Die erste Forall-Schleife ist mir dabei klar. Bei der zweiten Forall-Schleife stehe ich allerdings auf dem Schlauch:
Man betrachtet dort die zu einem Knoten inzidenten Kanten, sofern auf diesen ein Fluss fließt und wenn der Quellknoten dieser Kante noch nicht markiert ist. In diesem Fall markiert man den Quellknoten dieser Kante und gibt dem Quellknoten dieser Kante als Vorgängerkante die Kante, die von dem Quellknoten ausgeht?
Ich blicke da einfach nicht ganz durch, was da der Sinn dahinter ist. Vielleicht arbeitet man da auch schon auf dem Restnetzwerk G(x)?

Naja, vll. hilft mir aber das Beispiel in Deinem Link nochmal, das durchzuarbeiten und trägt hoffentlich ein wenig zum Verständnis bei.

Gruß,
Marcel

Bezug
        
Bezug
MaxFlowLabeling/FordFulkerson: Antwort
Status: (Antwort) fertig Status 
Datum: 20:06 Do 13.08.2009
Autor: bazzzty

Hallo Marcel,

> wie bereits aus dem Threadtitel ersichtlich habe ich bei
> dem Algorithmus ein paar Verständnisschwierigkeiten.
> Generell ist mir das Prinzip des Algorithmus klar: Man
> sucht nach erhöhenden Pfaden, indem man alle Knoten, die
> über Kanten, auf denen man den Fluss erhöhen kann,
> labeled, und wenn der Zielknoten gelabeled wird, existiert
> ein solcher Pfad. Dieser wird mitberechnet und man erhöht
> den Fluss entlang dieses Pfades.

Okay. Und genau da ist schon der "Fehler". Im eigentlichen Graphen kann man Fluss zur Senke auch erhöhen, indem man einen Pfad findet, auf dem man (a) Kanten vorwärts benutzt, deren Kapazitätsgrenze noch nicht erreicht ist, aber auch (b) Kanten rückwärts benutzt, auf denen aktuell ein echt positiver Fluss ist. In vielen Darstellungen wird das abgebildet, indem man den Residualgraphen definiert, so wie bei []Wikipedia. Vielleicht siehst Du trotzdem, dass in dem Beispiel dort eine rote Kante eigentlich im Original eine andersherum gerichtete Kante ist, auf der bereits Fluss liegt, den man aber zurücknehmen kann, wenn es einem hilft.

Deine Implementierung berechnet einfach nicht explizit den Residualgraphen, sondern nutzt ihn implizit. Es gibt eine Kante von v nach w im Residualgraphen, wenn es entweder eine Kante v nach w gibt, die nicht ausgelastet ist, oder wenn es eine Kante w nach v gibt, auf der schon Fluss ist.

> Im Algorithmus selbst habe ich aber an (wenigstens) zwei
> Stellen Verständnisschwierigkeiten.

Ich denke, die Schwierigkeit ist immer dieselbe (siehe oben).

Ich streue mal ein paar Kommentare ein

>    while (true) [mm]\{[/mm]
>      node v;
>      forall_nodes(v,G)[mm]\{[/mm]
>        labeled[v]=false;
>        pred[v]=NULL;
>      [mm]\}[/mm]
>      labeled=true;
>      L.append;

klar, s ist erhöhend erreichbar.


> while(! L.empty()) [mm]\{[/mm]
>        node v=L.pop();
>        edge e;

Wir gucken uns immer einen erreichbaren Knoten aus der Liste an und suchen nach erreichbaren Nachbarn. Die Idee ist: in diesem Knoten könnte ich einen Überschuss erzeugen. Zu welchem Nachbarn kann ich den weiterreichen?

> forall_out_edges(e,v) [mm]\{[/mm]
>          if (flow[e]==cap[e]) continue;
>          node w=G.target(e);
>          if (labeled[w]) continue;
>          labeled[w]=true;
>          pred[w]=e;
>          L.append(w);
>        [mm]\}[/mm]

Klar: Kann ich einen Nachbarn mit einer Vorwärtskante erreichen, kann ich Überschuss weitergeben, wenn die Kante noch nicht voll ausgelastet ist.

>        // [mm](\star_1)[/mm] Die folgende Forall-Schleife ist mir
> unklar!!
>        forall_in_edges(e,v) [mm]\{[/mm]
>          if (flow[e]==0) continue;
>          node w=G.source(e);
>          if (labeled[w]==true) continue;
>          labeled[w]=true;
>          pred[w]=e;
> // [mm](\star_2)[/mm] Wieso wird hier [mm]e\,[/mm] als Vorgängerkante von
> [mm]w\,[/mm] definiert?
>          L.append(w);
>        [mm]\}[/mm]

Wenn ein Knoten erreichbar ist, indem ich "entgegen" der Kantenrichtung gehe, dann kann ich meinen Überfluss trotzdem abwälzen, nämlich, indem ich den Fluss auf der Kante absenke. Das geht nur dann, wenn auf der Kante aktuell Fluss ist. Und meine Vorgängerrelation heißt "von wem habe ich den Überschuss bekommen"?
In diesem Fall gibt v den Überschuss an w, auch wenn die Kante von w nach v zeigt. Im Residualgraphen wäre das eine Kante in die andere Richtung (oder je eine Kante in beide Richtungen, wenn der aktuelle Fluss echt zwischen 0 und der Kapazität liegt)

>
> if (labeled[t])
>          AUGMENT(G,s,t,cap,flow,pred)
>        else
>          break;
>    [mm]\}[/mm]
> [mm]\}[/mm]    
>
> void AUGMENT(const graph & G,node s, node t, const edge_array<int> & cap,edge_array<int> & flow, const node_array<edge> & pred)[mm]\{[/mm]
>    int delta=MAXINT;
>    node v=t;
>   
> while(v!=s)[mm]\{[/mm]
>      edge e=pred[v];
>      int r;
>      if (v==G.target(e))[mm]\{[/mm]
>        r=cap[e]-flow[e];
>        v=G.source(e);
>      [mm]\}[/mm]
> else [mm]\{[/mm]
>        r=flow[e];
>        v=G.target(e);
>      [mm]\}[/mm]
>      if (r < delta)
>        delta=r;
>    [mm]\}[/mm]
>   
> v=t;
>    while(v!=s) [mm]\{[/mm]
>      edge(e)=pred[v];
>      if (v==G.target[e]) [mm]\{[/mm]
>        flow[e]+=delta;
>        v=G.source(e);
>      [mm]\}[/mm]
>      else [mm]\{[/mm] //[mm](\star_3)[/mm] Was geschieht hier nun genau?

Wir haben, von s ausgehend, herausgefunden, dass man Überschuss durch geschicktes Anheben und Absenken von Flüssen auf Kanten bis zur Senke schieben kann. Wir wissen aber nicht, um wieviel wir den Fluss auf einen Schlag erhöhen können. Da hilft nur eins: Wir gehen den erhöhenden Pfad ab und schauen, was die größte Erhöhung ist, die alle Kanten mitmachen. Und Vorsicht! Eine Erhöhung entlang des Pfades heißt, dass wir bei einigen Kanten den Fluss erhöhen müssen (bei denen, die wir vorwärts gelaufen sind), und bei einigen Fluss verringern müssen (bei denen, die wir rückwärts gelaufen sind). Deswegen ist es relevant, ob die Kante Vorgänger des Ziels oder der Quelle der Kante ist!

> [s][s]Ich weiß, es ist sehr aufwendig, aber vll. kennt ja auch jemand ein Beispiel, an dem man der Sinn der Forall-Schleife von [mm](\star_1)[/mm] deutlich wird?

Ja. Stell Dir in diesem [a]Beispiel vor, alle Kanten haben Kapazität 1 und du wählst als erstes den grünen Pfad und erhöhst den Fluss auf den betroffenen Kanten um 1. Danach findest Du von dem linken Startknoten aus den unteren Knoten vorwärts, musst dann aber die mit Fluss belegte Kante zwischen den beiden mittleren Knoten gegen die Kantenrichtung gehen, also Fluss wieder absenken, um insgesamt noch zur Lösung zu kommen.

Gruß
Bastian

Dateianhänge:
Anhang Nr. 1 (Typ: pdf) [nicht öffentlich]
Bezug
                
Bezug
MaxFlowLabeling/FordFulkerson: Mitteilung
Status: (Mitteilung) Reaktion unnötig Status 
Datum: 20:08 Do 13.08.2009
Autor: bazzzty

man verzeihe mir die Durchstreichungen, ich hatte nicht die Zeit, den Code "in Form" zu bringen. Das ist keine Absicht.

Bezug
                
Bezug
MaxFlowLabeling/FordFulkerson: Mitteilung
Status: (Mitteilung) Reaktion unnötig Status 
Datum: 21:01 Do 13.08.2009
Autor: Marcel

Hallo bazzzty,

erstmal vielen Dank für Deine Antwort. Ich habe sie mir schonmal durchgelesen und etwas drüber nachgedacht, so langsam wird mir einiges klarer.

Leider fehlt mir gerade noch ein wenig die Zeit, da genauer reinzugucken, um herauszufinden, ob nun schon alles klar ist oder ob es doch noch Unklahrheiten gibt. Am Wochenende werde ich ein wenig mehr Zeit dafür haben und es mir zur genaueren Betrachtung auch nochmal ausdrucken. Ich werde mich dann gegebenenfalls nochmal melden.

Vorab aber schonmal vielen Dank für Deine Mühe und auch die Zeit, die Du Dir genommen hast. Ich denke, mein "erster Denkfehler" wurde schonmal beseitigt. Ich werde auch gleich schonmal das von Dir gebrachte Beispiel durchgehen. Ich kenne es ähnlich, nur, dass man dann nur die "mittlere Kante" mit Kapazität 1 versieht und die anderen mit einer extrem hohen Kapazität [mm] ($10^8$ [/mm] oder noch größer z.B.). Das war dann ein Worst-Case-Beispiel für die Laufzeit, wobei mir, denke ich, auch erst jetzt wirklich klar ist, wie diese extrem schlechte Laufzeit dann bei diesem Labeling-Alg. zustandekommt.

Beste Grüße,
Marcel

Bezug
                
Bezug
MaxFlowLabeling/FordFulkerson: Frage (beantwortet)
Status: (Frage) beantwortet Status 
Datum: 22:01 Do 13.08.2009
Autor: Marcel

Hallo bazzzty,

doch noch eine ganz kleine kurze Nachfrage:
Wenn ich das richtig verstehe, ist es so, dass man anhand des Restnetzwerkes (bzw. des Residualgraphen; der ist mir übrigens auch bekannt und wurde in der Vorlesung auch eingeführt) erkennt, ob es einen Pfad im Ausgangsgraphen gibt, auf dem man den Fluss erhöhen kann. (Ich denke mir das nun so, dass der Ausgangsgraph immer bestehen bleibt, und man dann an die jeweilige Kante [mm] $e\,$ [/mm] dann ein Paar [mm] $(x(e),k(e))\,$ [/mm] schreibt, wobei [mm] $x(e)\,$ [/mm] den aktuellen Flußwert der Kante und [mm] $k(e)\,$ [/mm] die Kapazität der Kante bezeichnet).
Wenn man dann im Residualgraphen einen Pfad von der Quelle zur Senke finde (mithilfe des Labelingsalgorithmus wird dort einer gefunden, wenn ein solcher existiert), dann wählen wir den ersten, den das obige Labeling findet und verändern entlang dieses Pfades den Fluss. Durch Vergleich der Kante im Residualgraphen mit der Kante im Ausgangsgraphen "wissen wir dann" sozusagen, ob wir bzgl. der betrachteten Kante dann Fluss erhöhen oder absenken müssen. (Präzise steht das ja im obigen Algorithmus; das erklärt mir nun auch, warum bei der Augment-Funktion dort unterschieden wird, ob v Anfangs oder Endknoten der Kante e ist).

Also so grob gesagt:
Die "Pfadsuche", entlang der wir den Fluß verändern, findet eigentlich im Residualgraphen des Flußes statt; nur: die obige Implementierung arbeitet nicht wirklich auf dem Residualgraphen, sonden stets auf dem Ausgangsgraphen und benutzt die Pfadsuche im Residualgraphen nur (auch, ohne diesen zu berechnen; also meinetwegen könnte man sagen, der "Residualgraph wird nur in theoretischer Form" benutzt), um einen Pfad zu finden, entlang dem wir den Fluss (im Ausgangsgraphen, an dem wir an jede Kante auch den Flusswert mit dranschreiben) abändern.

Ich hoffe, ich drücke mich einigermaßen verständlich aus. Falls ja: Dann denke ich, dass ich das nun doch verstanden habe. Falls nein:
Entweder drücke ich mich dann irgendwo falsch aus, oder es ist doch noch irgendwo ein Denkfehler meinerseits vorhanden. Im letztgenannten Falle wäre es nett, sofern Du ihn auch siehst, wenn Du mich drauf hinweisen würdest :-)

Beste Grüße,
Marcel

Bezug
                        
Bezug
MaxFlowLabeling/FordFulkerson: Antwort
Status: (Antwort) fertig Status 
Datum: 08:59 Fr 14.08.2009
Autor: bazzzty


>  Wenn ich das richtig verstehe, ist es so, dass man anhand
> des Restnetzwerkes (bzw. des Residualgraphen; der ist mir
> übrigens auch bekannt und wurde in der Vorlesung auch
> eingeführt) erkennt, ob es einen Pfad im Ausgangsgraphen
> gibt, auf dem man den Fluss erhöhen kann. (Ich denke mir
> das nun so, dass der Ausgangsgraph immer bestehen bleibt,
> und man dann an die jeweilige Kante [mm]e\,[/mm] dann ein Paar
> [mm](x(e),k(e))\,[/mm] schreibt, wobei [mm]x(e)\,[/mm] den aktuellen
> Flußwert der Kante und [mm]k(e)\,[/mm] die Kapazität der Kante
> bezeichnet).
>  Wenn man dann im Residualgraphen einen Pfad von der Quelle
> zur Senke finde (mithilfe des Labelingsalgorithmus wird
> dort einer gefunden, wenn ein solcher existiert), dann
> wählen wir den ersten, den das obige Labeling findet und
> verändern entlang dieses Pfades den Fluss. Durch Vergleich
> der Kante im Residualgraphen mit der Kante im
> Ausgangsgraphen "wissen wir dann" sozusagen, ob wir bzgl.
> der betrachteten Kante dann Fluss erhöhen oder absenken
> müssen. (Präzise steht das ja im obigen Algorithmus; das
> erklärt mir nun auch, warum bei der Augment-Funktion dort
> unterschieden wird, ob v Anfangs oder Endknoten der Kante e
> ist).

Genau, sehr schön.

> Also so grob gesagt:
>  Die "Pfadsuche", entlang der wir den Fluß verändern,
> findet eigentlich im Residualgraphen des Flußes statt;

Exakt.

> nur: die obige Implementierung arbeitet nicht wirklich auf
> dem Residualgraphen, sonden stets auf dem Ausgangsgraphen
> und benutzt die Pfadsuche im Residualgraphen nur (auch,
> ohne diesen zu berechnen; also meinetwegen könnte man
> sagen, der "Residualgraph wird nur in theoretischer Form"
> benutzt), um einen Pfad zu finden, entlang dem wir den
> Fluss (im Ausgangsgraphen, an dem wir an jede Kante auch
> den Flusswert mit dranschreiben) abändern.

Genau das ist der Punkt. Ich denke, Du hast alles verstanden.
So eine Implementierung kann einen ganz schön verwirren: Aus theoretischer Sicht ist die Definition eines Residualgraphen elegant, aber bei einer Implementierung ist das letztlich nur unnötiger Aufwand.

> Ich hoffe, ich drücke mich einigermaßen verständlich
> aus. Falls ja: Dann denke ich, dass ich das nun doch
> verstanden habe. Falls nein: ...


Definitiv JA ;)

Gruß
Bastian

Bezug
                                
Bezug
MaxFlowLabeling/FordFulkerson: Mitteilung
Status: (Mitteilung) Reaktion unnötig Status 
Datum: 15:10 Fr 14.08.2009
Autor: Marcel

Hallo Bastian,


> >  Wenn ich das richtig verstehe, ist es so, dass man anhand

> > des Restnetzwerkes (bzw. des Residualgraphen; der ist mir
> > übrigens auch bekannt und wurde in der Vorlesung auch
> > eingeführt) erkennt, ob es einen Pfad im Ausgangsgraphen
> > gibt, auf dem man den Fluss erhöhen kann. (Ich denke mir
> > das nun so, dass der Ausgangsgraph immer bestehen bleibt,
> > und man dann an die jeweilige Kante [mm]e\,[/mm] dann ein Paar
> > [mm](x(e),k(e))\,[/mm] schreibt, wobei [mm]x(e)\,[/mm] den aktuellen
> > Flußwert der Kante und [mm]k(e)\,[/mm] die Kapazität der Kante
> > bezeichnet).
>  >  Wenn man dann im Residualgraphen einen Pfad von der
> Quelle
> > zur Senke finde (mithilfe des Labelingsalgorithmus wird
> > dort einer gefunden, wenn ein solcher existiert), dann
> > wählen wir den ersten, den das obige Labeling findet und
> > verändern entlang dieses Pfades den Fluss. Durch Vergleich
> > der Kante im Residualgraphen mit der Kante im
> > Ausgangsgraphen "wissen wir dann" sozusagen, ob wir bzgl.
> > der betrachteten Kante dann Fluss erhöhen oder absenken
> > müssen. (Präzise steht das ja im obigen Algorithmus; das
> > erklärt mir nun auch, warum bei der Augment-Funktion dort
> > unterschieden wird, ob v Anfangs oder Endknoten der Kante e
> > ist).
>  
> Genau, sehr schön.
>  
> > Also so grob gesagt:
>  >  Die "Pfadsuche", entlang der wir den Fluß verändern,
> > findet eigentlich im Residualgraphen des Flußes statt;
>
> Exakt.
>
> > nur: die obige Implementierung arbeitet nicht wirklich auf
> > dem Residualgraphen, sonden stets auf dem Ausgangsgraphen
> > und benutzt die Pfadsuche im Residualgraphen nur (auch,
> > ohne diesen zu berechnen; also meinetwegen könnte man
> > sagen, der "Residualgraph wird nur in theoretischer Form"
> > benutzt), um einen Pfad zu finden, entlang dem wir den
> > Fluss (im Ausgangsgraphen, an dem wir an jede Kante auch
> > den Flusswert mit dranschreiben) abändern.
>
> Genau das ist der Punkt. Ich denke, Du hast alles
> verstanden.
>  So eine Implementierung kann einen ganz schön verwirren:
> Aus theoretischer Sicht ist die Definition eines
> Residualgraphen elegant, aber bei einer Implementierung ist
> das letztlich nur unnötiger Aufwand.

Ja. Ich denke, beim Algorithmus habe ich einfach nicht mehr dran gedacht, dass diese Pfadsuche eigentlich im Residualgraphen stattfinden muss, der vorliegende Graph ja aber (bzgl. Knoten und Kanten) unverändert bleibt. Ich habe da wohl Kanten des Residualgraphen auch im Ausgangsgrpahen verwenden wollen; aber der Residualgraph wird ja nur "theoretisch" genutzt.
Eigentlich ein blöder Fehler. Aber trotzdem gut, denn ich denke, dass mir diese Verwirrung in Zukunft nicht mehr unterlaufen wird und ich jetzt auch erkenne, wenn jemand den gleichen Fehler macht. Ist ja sicher auch kein untypischer Fehler, wie ich vermute ;-)
  

> > Ich hoffe, ich drücke mich einigermaßen verständlich
> > aus. Falls ja: Dann denke ich, dass ich das nun doch
> > verstanden habe. Falls nein: ...
>  
>
> Definitiv JA ;)

Alles klar. Vielen Dank für Deine Hilfe und schönes Wochenende :-) (Und natürlich auch nochmal Danke an Karl!)

Beste Grüße,
Marcel

Bezug
Ansicht: [ geschachtelt ] | ^ Forum "Operations Research"  | ^^ Alle Foren  | ^ Forenbaum  | Materialien


^ Seitenanfang ^
www.unimatheforum.de
[ Startseite | Forum | Wissen | Kurse | Mitglieder | Team | Impressum ]