Wenden wir Branch and Bound auf Knapsack an . Hoffentlich wird Ihnen dies das Konzept klar machen.
Wir haben Artikel mit den Bezeichnungen 1 bis n . v i ist der Wert des i- ten Elements und w i sein Gewicht. Wir versuchen, sie in einen Rucksack zu passen, der insgesamt bis zu T Gewicht enthalten kann , und wir versuchen, die Summe der Werte des Gegenstands, den wir in den Rucksack legen, zu maximieren.n1nvichichwichT.
Der gewöhnliche Backtrack-Ansatz ist unsere Basis. Wir legen zuerst in die Packung und lösen dann das Problem für die verbleibenden n - 1 Elemente mit Rekursion. Wir entfernen dann v 1 aus dem Paket und lösen das Problem für die verbleibenden n - 1 Elemente erneut und geben die beste Konfiguration zurück, die wir gefunden haben.v1n - 1v1n - 1
Dieses Backtracking ist der 'Branch'-Teil von Branch and Bound. Sie verzweigen sich (im Fall von Knapsack) in zwei Fällen: "Element ist Teil der Lösung" und "Element i ist nicht Teil der Lösung". Sie können dies als binären Baum visualisieren, wobei das linke Kind ein Fall und das rechte Kind der andere Fall ist. Dieser Baum ist der Suchbaumichich (oder Suchraum ): Seine Tiefe beträgt , und er hat daher O ( 2 n ) Knoten. Der Algorithmus hat daher eine exponentielle Laufzeit in der Anzahl der Elemente.nO ( 2n)
Jetzt kommen wir zum Teil 'Gebunden': Wir versuchen, Kriterien zu finden, bei denen wir sagen können, dass diese Konfiguration niemals funktioniert, also könnten wir uns genauso gut nicht die Mühe machen, dies zu berechnen. Ein Beispiel für ein solches Kriterium ist "das Gewicht der Gegenstände, die wir bereits in den Rucksack gelegt haben, überschreitet ": Wenn wir beispielsweise die ersten n / 2 Gegenstände zum Rucksack hinzugefügt haben und dieser daher bereits voll ist, gibt es Es macht keinen Sinn, zu versuchen, die Gegenstände n / 2 + 1 bis n im Rucksack zu platzieren, aber es macht auch keinen Sinn, zu versuchen, eine Teilmenge von n / 2 + 1 bis n zu passenT.n / 2n / 2 + 1nn/2+1nim Rucksack, da er bereits voll ist, sparen wir also ca. Fälle. Ein anderes Beispiel ist " Selbst wenn ich alle verbleibenden Elemente eingebe, überschreitet der Wert der Elemente, die ich eingegeben habe, nicht die beste Konfiguration, die ich bisher gefunden habe ".2n/2
Diese Kriterien schneiden im Wesentlichen Teile des Suchbaums ab: An einem Knoten sagen Sie beispielsweise "Der linke Teilbaum gibt mir keine bessere Konfiguration, weil X", sodass Sie diesen Teilbaum vergessen und ihn nicht untersuchen. Ein Teilbaum der Tiefe , den Sie auf diese Weise ausschneiden, spart Ihnen O ( 2 d ) Knoten, was mit etwas Glück eine ziemliche Geschwindigkeitssteigerung bedeuten kann.dO(2d)
Beachten Sie, dass dies als " Begrenzung " bezeichnet wird, da es sich normalerweise um eine Art Unter- oder Obergrenze handelt: Für das Kriterium " Selbst wenn ich alle verbleibenden Elemente eingebe, überschreitet der Wert der Elemente, die ich eingegeben habe, nicht die beste Konfiguration." Ich habe bisher festgestellt , dass der Wert Ihrer besten Konfiguration bisher eine Untergrenze für die beste Konfiguration ist. Alles, was diese Untergrenze niemals überschreitet, ist zum Scheitern verurteilt.
Sie können den Teil "Bounding" so komplex gestalten, wie Sie möchten. Zum Beispiel werden ganzzahlige Programmierprobleme häufig durch Relaxationen gelöst: Sie entspannen Ihr Programm zu einem linearen Programm, das Sie in Polynomzeit lösen können, und dann können Sie viele Fälle für Ihre binären Variablen wegwerfen, die sowieso nie funktionieren. Anschließend verzweigen Sie in die verbleibenden Optionen.
Beachten Sie, dass Branch and Bound in der Praxis normalerweise nur zu einer Geschwindigkeitssteigerung führt, theoretisch jedoch nicht: Es ist schwer zu sagen, wie viel des Suchbaums mithilfe Ihrer Heuristiken ausgeschnitten wird. Dies wird durch die Anzahl der verschiedenen Heuristiken belegt, die in der Praxis für solche Probleme verwendet werden. Wenn Sie Pech haben, bleibt der verbleibende Suchbaum trotz vieler Einschränkungen riesig.