Wie man den gierigen Algorithmus beweist, ist richtig


29

Ich habe einen gierigen Algorithmus, von dem ich vermute, dass er richtig ist, aber ich bin mir nicht sicher. Wie überprüfe ich, ob es korrekt ist? Was sind die Techniken, um zu beweisen, dass ein gieriger Algorithmus korrekt ist? Gibt es gemeinsame Muster oder Techniken?

Ich hoffe, dass dies eine Referenzfrage wird, auf die Anfänger verweisen können. daher sein weiter gefasster Anwendungsbereich. Bitte achten Sie darauf, allgemeine, didaktisch aufbereitete Antworten zu geben, die an mindestens einem Beispiel illustriert sind, aber dennoch viele Situationen abdecken. Vielen Dank!



Können wir beweisen, dass ein gieriger Algorithmus korrekt ist, indem wir ein Matroid oder ein Greedoid verwenden?
ZDM

Antworten:


24

Letztendlich benötigen Sie einen mathematischen Korrektheitsnachweis. Ich werde im Folgenden auf einige Beweistechniken eingehen, aber bevor ich darauf eingehe, möchte ich Ihnen einige Zeit sparen: Bevor Sie nach einem Beweis suchen, versuchen Sie es mit zufälligen Tests.

Zufällige Tests

Als ersten Schritt empfehle ich Ihnen, Ihren Algorithmus anhand von Zufallstests zu testen. Es ist erstaunlich, wie effektiv dies ist: Meiner Erfahrung nach scheint zufälliges Testen für gierige Algorithmen unangemessen effektiv zu sein. Verbringen Sie 5 Minuten damit, Ihren Algorithmus zu verschlüsseln, und sparen Sie sich möglicherweise ein oder zwei Stunden, um einen Beweis zu finden.

Die Grundidee ist einfach: Implementieren Sie Ihren Algorithmus. Implementieren Sie auch einen Referenzalgorithmus, von dem Sie wissen, dass er korrekt ist (z. B. einen, der alle Möglichkeiten ausgiebig ausprobiert und das Beste ausnutzt). Es ist in Ordnung, wenn Ihr Referenzalgorithmus asymptotisch ineffizient ist, da Sie dies nur auf kleinen Probleminstanzen ausführen. Generieren Sie dann nach dem Zufallsprinzip eine Million kleiner Probleminstanzen, führen Sie beide Algorithmen aus und überprüfen Sie, ob Ihr Kandidatenalgorithmus in jedem Fall die richtige Antwort gibt.

Empirisch werden Sie dies häufig bei zufälligen Tests feststellen, wenn der Algorithmus Ihres Kandidaten für eine Gier inkorrekt ist. Wenn es in allen Testfällen richtig zu sein scheint, sollten Sie mit dem nächsten Schritt fortfahren: der Erstellung eines mathematischen Beweises für die Richtigkeit.

Mathematische Korrektheitsnachweise

OK, wir müssen also beweisen, dass unser gieriger Algorithmus korrekt ist: dass er die optimale Lösung ausgibt (oder, wenn es mehrere optimale Lösungen gibt, die gleich gut sind, dass er eine davon ausgibt).

Das Grundprinzip ist intuitiv:

Prinzip: Wenn Sie nie eine schlechte Wahl treffen, tun Sie alles in Ordnung.

Gierige Algorithmen beinhalten normalerweise eine Folge von Auswahlmöglichkeiten. Die grundlegende Beweisstrategie ist, dass wir versuchen, zu beweisen, dass der Algorithmus niemals eine schlechte Wahl trifft. Gierige Algorithmen können nicht zurückverfolgen - sobald sie eine Entscheidung getroffen haben, sind sie festgeschrieben und werden diese Entscheidung niemals rückgängig machen -, daher ist es wichtig, dass sie niemals eine schlechte Entscheidung treffen.

Was wäre eine gute Wahl? Wenn es eine einzige optimale Lösung gibt, ist es leicht zu erkennen, was eine gute Wahl ist: jede Wahl, die mit der von der optimalen Lösung getroffenen identisch ist. Mit anderen Worten, wir werden versuchen zu beweisen, dass zu jedem Zeitpunkt der Ausführung der Greedy-Algorithmen die bisher vom Algorithmus getroffene Auswahlsequenz genau mit einem Präfix der optimalen Lösung übereinstimmt. Wenn es mehrere gleich gute optimale Lösungen gibt, ist eine gute Wahl eine, die mit mindestens einem der Optima übereinstimmt. Mit anderen Worten, wenn die Auswahlreihenfolge des Algorithmus bisher mit einem Präfix einer der optimalen Lösungen übereinstimmt, ist bis jetzt alles in Ordnung (es ist noch nichts schiefgegangen).

Um das Leben zu vereinfachen und Ablenkungen zu vermeiden, konzentrieren wir uns auf den Fall, dass es keine Bindungen gibt: Es gibt eine einzige, einzigartige optimale Lösung. Alle Maschinen werden auf den Fall übertragen, dass es ohne grundlegende Änderungen mehrere gleich gute Optima geben kann, aber Sie müssen ein bisschen vorsichtiger mit den technischen Details umgehen. Ignorieren Sie zunächst diese Details und konzentrieren Sie sich auf den Fall, in dem die optimale Lösung einzigartig ist. So können Sie sich auf das Wesentliche konzentrieren.

Es gibt ein sehr verbreitetes Beweismuster, das wir verwenden. Wir werden hart arbeiten, um die folgende Eigenschaft des Algorithmus zu beweisen:

Behauptung: Sei die vom Algorithmus ausgegebene Lösung und OSO die optimale Lösung. Wenn unterscheidet sich von ist O , dann können wir optimieren O eine andere Lösung zu erhalten O * , die sich von ist O und streng besser als O .SOOOOO

Beachten Sie, warum dies nützlich ist. Wenn die Behauptung wahr ist, folgt, dass der Algorithmus korrekt ist. Dies ist im Grunde ein Beweis durch Widerspruch. Entweder ist dasselbe wie O oder es ist anders. Wenn es anders ist, können wir eine andere Lösung findenSO , die als streng besser OOO - aber das ist ein Widerspruch, wie wir definierten die optimale Lösung zu sein , und es kann keine Lösung sein , die als besser. Wir sind gezwungen zu folgern, dass S nicht anders sein kann als O ; S muss immer gleich O seinOSOSODas heißt, der Greedy-Algorithmus gibt immer die richtige Lösung aus. Wenn wir die Behauptung oben beweisen können, haben wir unseren Algorithmus als korrekt erwiesen.

Fein. Wie beweisen wir die Behauptung? Wir denken an eine Lösung als einen Vektor ( S 1 , , S n ), der der Folge von n Auswahlen entspricht, die vom Algorithmus getroffen wurden, und ebenso denken wir an die optimale Lösung O als einen Vektor ( O 1 , , O n ) entsprechend der Reihenfolge der Entscheidungen, die zu O führen würden . Wenn S von O verschieden ist , muss ein Index i existieren, bei dem S i ≠ istS(S1,,Sn)nO(O1,,On)OSOich ; wir werden uns auf das kleinste konzentrieren, wie ich . Dannwir zwicken O , indem O ein wenig in der i - ten Position Spiel S i ,heißt, werden wir die optimale Lösung optimieren O durch die Änderung i - te Wahl auf die von der GreedyAlgorithmus Auserwählte, und dann Wir werden zeigen, dass dies zu einer noch besseren Lösung führt. Insbesondere definieren wir O als so etwas wieSichOichichOOichSichOichO

O=(O1,O2,,Oich-1,Sich,Oich+1,Oich+2,,On),

mit der Ausnahme, dass wir den -Teil häufig leicht ändern müssen, um die globale Konsistenz zu gewährleisten. Ein Teil der Beweisstrategie beinhaltet ein gewisses Maß an Klugheit bei der Definition von O . Dann wird das Fleisch des Beweises darin bestehen, Fakten über den Algorithmus und das Problem zu verwenden, um zu zeigen, dass O streng besser als O istOich+1,Oich+2,,OnOOO; Hier benötigen Sie einige problemspezifische Einblicke. Irgendwann müssen Sie sich mit den Details Ihres spezifischen Problems befassen. Dies vermittelt Ihnen jedoch einen Eindruck von der Struktur eines typischen Korrektheitsnachweises für einen gierigen Algorithmus.

Ein einfaches Beispiel: Teilmenge mit maximaler Summe

Dies ist möglicherweise einfacher zu verstehen, wenn Sie ein einfaches Beispiel im Detail durcharbeiten. Betrachten wir das folgende Problem:

Eingabe: Eine Menge von ganzen Zahlen, eine ganze Zahl k Ausgabe: Eine Menge S U der Größe k, deren Summe so groß wie möglich istUk
SUk

Es gibt einen natürlichen Greedy-Algorithmus für dieses Problem:

  1. Setze .S: =
  2. Für : i:=1,2,,k
    • Sei die größte Zahl in U , die noch nicht ausgewählt wurde (dh ixiUi -größte Zahl in ). HinzufügenU zu S .xiS

Zufällige Tests legen nahe, dass dies immer die optimale Lösung ergibt. Lassen Sie uns also formal beweisen, dass dieser Algorithmus korrekt ist. Beachten Sie, dass die optimale Lösung einzigartig ist, sodass wir uns nicht um Krawatten kümmern müssen. Lassen Sie uns die oben skizzierte Behauptung beweisen:

Behauptung: Sei die von diesem Algorithmus ausgegebene Lösung am Eingang U , k und O die optimale Lösung. Wenn SSU,kO , können wir eine andere Lösung konstruierenSOderen Summe noch größer als O ist .OO

Beweis. Angenommen, , und sei i der Index der ersten Iteration, in der x iO ist . (Ein solcher Index i muss existieren, da wir S O angenommen haben und nach der Definition des Algorithmus S = { x 1 , , x k } haben .) Da (nach Annahme) i minimal ist, müssen wir haben x 1 , , xSOixiOiSOS={x1,,xk}iund insbesonderex1,,xi1O hat die Form O = { x 1 , x 2 , ... , x i - 1 , x ' i , x ' i + 1 , ... , x ' n } , wobei die Zahlen x 1 , ... , x i - 1 , x ' i , ... , x ' nOO={x1,x2,,xi1,xi,xi+1,,xn}x1,,xi1,xi,,xnsind in absteigender Reihenfolge aufgeführt. Wenn wir uns ansehen, wie der Algorithmus auswählt , sehen wir, dass wir x i > x ' j für alle j i haben müssen . Insbesondere gilt x i > x ' i . Definiere also O = O { x i } { x i } , dh wir erhalten O ∗, indem wir die i- te Zahl in O löschenx1,,xixi>xjjixi>xiO=O{xi}{xi}OiOund Hinzufügen von . Nun ist die Summe der Elemente von O die Summe der Elemente von O plus x i - x ' i und x i - x ' i > 0 , so dass die Summe von O streng größer als die Summe von O ist . Dies beweist die Behauptung. xiOOxixixixi>0OO

Die Intuition hier ist, dass, wenn der gierige Algorithmus jemals eine Wahl trifft, die mit inkonsistent ist , wir beweisen können, dass O noch besser sein könnte, wenn es so modifiziert würde, dass es das Element enthält, das zu diesem Zeitpunkt vom gierigen Algorithmus ausgewählt wurde. Da O optimal ist, kann es unmöglich einen Weg geben, es noch besser zu machen (das wäre ein Widerspruch). Die einzige verbleibende Möglichkeit ist, dass unsere Annahme falsch war: Mit anderen Worten, der gierige Algorithmus wird niemals eine Wahl treffen das heißt nicht mit O .OOOO

Dieses Argument wird oft als Austauschargument oder Austauschlemma bezeichnet . Wir fanden den ersten Ort, an dem sich die optimale Lösung von der gierigen Lösung unterscheidet, und stellten uns vor, dieses Element von gegen die entsprechende gierige Wahl auszutauschen (ausgetauschtes x ' iOxi gegen ). Einige Analysen haben gezeigt, dass dieser Austausch nur die optimale Lösung verbessern kann - aber per Definition kann die optimale Lösung nicht verbessert werden. Die einzige Schlussfolgerung ist also, dass es keinen Ort geben darf, an dem sich die optimale Lösung von der gierigen Lösung unterscheidet. Wenn Sie ein anderes Problem haben, suchen Sie nach Möglichkeiten, dieses Austauschprinzip in Ihrer spezifischen Situation anzuwenden.xi


Dies ist eine alte Frage, aber für mich das erste Ergebnis in Google. Die Leitung then we can tweak O to get another solution O∗ that is different from O and strictly better than Overwirrt mich. Wenn es mehrere optimale Lösungen gibt, ist es möglich, dass S != Obeide immer noch optimal sind. wir können O optimieren, um "eher wie" S zu sein (O ∗ zu erschaffen) und dennoch genauso gut zu sein wie (nicht strictly better than) O.
citelao

@ Citelao, es tut mir leid zu hören, dass es Sie verwirrt. Leider bin ich mir nicht sicher, wie ich es deutlicher erklären soll. Ja, es kann mehrere optimale Lösungen geben, die alle denselben Wert haben. Das ist richtig. Was Sie geschrieben haben und was ich geschrieben habe, sind beide gültig; es gibt keinen widerspruch. Der Unterschied besteht darin, dass das, was Sie geschrieben haben, nicht dazu beiträgt, einen gierigen Algorithmus als richtig zu beweisen. was ich geschrieben habe macht. Ich kann nur vorschlagen, das, was ich geschrieben habe, noch einmal durchzugehen und zu prüfen, ob Sie herausfinden können, wie nützlich das ist, was ich geschrieben habe. Wenn das nicht hilft, finden Sie vielleicht einen anderen Artikel. Mir ist klar, dass es schwierig und verwirrend ist.
DW

1
Danke für die schnelle Antwort! Ich habe den Punkt verpasst, an dem Sie sich darauf konzentrieren, den Algorithmus zu beweisen, wenn es ihn nur gibt a single, unique optimal solution. Da es bei dieser Frage darum geht, jeden gierigen Algorithmus als richtig zu beweisen , möchte ich eine Antwort für Fälle geben, in denen mehrere optimale Lösungen existieren können. Es ist schon eine Weile her, dass ich all dies studiert habe, aber reicht es nicht aus, zu beweisen, dass Sie jedes Element O_i in einer optimalen Lösung O austauschen können, die sich von der alg unterscheidet. Lösung S mit S_i und noch eine Lösung O ', die nicht schlechter als O ist?
Citelao

@citelao, die Technik gilt auch für Fälle, in denen es mehrere optimale Lösungen gibt. Ich schlug vor, mich auf den Fall zu konzentrieren, in dem die optimale Lösung nur dann einzigartig ist, wenn Sie dies zum ersten Mal sehen, ist es einfacher zu verstehen, wie diese Beweise in dieser Umgebung funktionieren. Die gleiche Strategie funktioniert jedoch auch, wenn es mehrere optimale Lösungen gibt. Ich schlage vor, dies zu untersuchen, um sicherzustellen, dass Sie verstehen, wie es funktioniert, wenn es eine einzige optimale Lösung gibt, und es dann auf den allgemeinen Fall anzuwenden. Ich denke auch, dass es für Sie hilfreich sein könnte, ein paar Beispielbeweise für gierige Algorithmen zu studieren.
DW

Um Ihre letztere Frage zu beantworten, reicht das nicht aus. Das beweist nicht, dass S optimal ist. (Wenn Sie nur fordern, dass O 'nicht schlechter als O ist, gibt es Fälle, in denen S nicht optimal ist, es jedoch möglich ist, diese Art von Austausch durchzuführen. Dies beweist, dass es möglich ist, ein O' zu erzielen, das nicht schlechter ist als O nicht Ich kann nicht beweisen, ob S optimal ist und nicht, dass der gierige Algorithmus korrekt ist. Ich empfehle, die in der Antwort beschriebene Methode etwas genauer zu untersuchen. Es ist schwierig. Der Beweis durch Widerspruch ist oft schwierig zu verstehen.)
DW

14

Ich werde den folgenden einfachen Sortieralgorithmus als Beispiel verwenden:

repeat:
  if there are adjacent items in the wrong order:
     pick one such pair and swap
  else
     break

Um die Richtigkeit zu beweisen, benutze ich zwei Schritte.

  • Zuerst zeige ich, dass der Algorithmus immer terminiert.
  • Dann zeige ich, dass die Lösung, bei der es endet, die ist, die ich will.

Für den ersten Punkt wähle ich eine geeignete Kostenfunktion aus, für die ich zeigen kann, dass der Algorithmus sie in jedem Schritt verbessert.

In diesem Beispiel wähle ich die Anzahl der Inversionen in der Eingabeliste. Eine Inversion in einer Liste ist ein Paar von Einträgen A [ i ] , A [ j ], so dass A [ i ] > A [ j ] aber i < j ist . Die Anzahl der Inversionen ist immer nicht negativ und eine sortierte Liste enthält 0 Inversionen.AA[i]A[j]A[i]>A[j]i<j

A[i]A[i+1]A[i],A[i+1] , lässt jedoch alle anderen Inversionen unberührt. Daher wird die Anzahl der Inversionen bei jeder Iteration reduziert.

Dies beweist, dass der Algorithmus schließlich beendet wird.

Die Anzahl der Inversionen in einer sortierten Liste ist 0. Wenn alles gut geht, reduziert der Algorithmus die Anzahl der Inversionen auf 0. Wir müssen nur zeigen, dass es nicht in einem lokalen Minimum hängen bleibt.

Normalerweise beweise ich das durch Widerspruch. Ich gehe davon aus, dass der Algorithmus angehalten hat, aber die Lösung nicht korrekt ist. Im Beispiel bedeutet dies, dass die Liste noch nicht sortiert ist, aber keine benachbarten Elemente in der falschen Reihenfolge vorhanden sind.

A[i]EIN[j]ich<jEIN[ich]>EIN[j]ichjich+1<jEIN[ich]<EIN[ich+1]EIN[ich+1]<EIN[j]EIN[ich]<EIN[j]

Dies beweist, dass der Algorithmus nur stoppt, wenn die Liste sortiert ist. Und damit sind wir fertig.


The techniques explained are so general that they virtually have nothing particular about greedy algorithm, the topic of this question.
Apass.Jack
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.