Systematische Suche WS13-14
Inhaltsverzeichnis |
Rucksackprobleme
Aus einer Menge von Gegenständen die einen Wert w und ein Gewicht g besitzen, gilt es einen Rucksack zu füllen bei dem der Gesamtwert der eingepackten Gegenstände maximal ist, ohne die Kapizitätsgrenze K des Rucksacks zu überschreiten.
Allgemein beschreiben Rucksackprobleme: Beladungsprobleme, Verschnittprobleme oder Probleme der Budgetkontrolle.
Beispiel
Thomas will sein Geld anlegen und versucht ein Investment-Portfolio zu erstellen, aus dem er sich maximalen Gewinn erhofft. Er hat 10000€ (K) zur Verfügung und will diese in unterschiedliche Aktien verteilen, welche eine Bewertung (w) und einen festen zu investierenden Wert (g) besitzen. Nun geht es darum ein Portfolio zusammenzustellen (Rucksack), in welchem die Gesamtbewertung aller gekauften Aktien maximal ist, dabei darf sein Budget nicht überzogen werden.
Zur Verfügung stehende Aktien:
| Aktie | Wert (in €) | Bewertung (0-10, höher ist besser) |
| Mapple | 2500 | 8 |
| Minisoft | 3000 | 4 |
| Le-Nogo | 5000 | 5 |
| Wogitech | 6000 | 3 |
| Joogle | 4000 | 7 |
Varianten
Es gibt viele unterschiedliche Formen des Rucksackproblems:
- 0/1 Rucksackproblem:
Hier wird ein Gegenstand entweder vollständig (1) oder gar nicht (0) eingepackt. Außerdem darf der selbe Gegenstand nur einmal eingepackt werden. - Bruchteil-Rucksackproblem:
Man kann einen beliebigen Teil t, mit 0\% \le t \le 100\%, eines Gegenstandes einpacken. - Unbeschränktes Rucksackproblem:
Bei dieser Variante des Problems gibt es keine Kapazitätsobergrenze, d.h. K = \infty. - Teilmengen-Summen-Problem (subset-sum problem):
In diesem speziellen Fall geht es darum die Gewichtskapazität des Rucksacks optimal auszunutzen, da der Wert mit dem Gewicht übereinstimmt, d.h. g_i = w_i für alle i.
In diesem Artikel wird ausschließlich das 0/1 Rucksackproblem betrachtet. Bruchteil-Rucksackprobleme werden im Artikel der Greedy-Algorithmen behandelt.
Beschränkung des Suchbaumes
Tiefensuche mit Beschränkung
Bei der beschränkten Tiefensuche wird nun auch die Kapazitätsbeschränkung (K) beim "Packen des Rucksacks" mit einbezogen. Im folgenden Beispiel ist eine Prozedur zur Erstellung eines Berechnungsprotokolles zur Lösung des Problems unter Berücksichtigung von K in Scheme dargestellt:
Am reduzierten Suchbaum zu erkennen ist, das lediglich die Blätter (10,30), (30), (10) und () die gewählte Kapazitätsbeschränkung erfüllen. Gesucht ist allerdings der größtmögliche Wert: Es wird bei w_i = g_i
Nichtdeterminismus
Beim Rucksackproblem wird der Suchprozess bei der Tiefensuche als Baum dargestellt. Dieser Baum existiert aber nicht wirklich, d.h. er wird nicht als Datenstruktur repräsentiert.
Der Programmierer denkt in Bäumen, wenn er versucht das Verfahren in seiner Programmiersprache implementiert. Bietet die gewählte Programmiersprache das Mittel Rekursion, kann das die Arbeit weiter vereinfachen. Denn so kann die rekursive Baumstruktur direkt in eine rekursive Programmstruktur abgebildet werden. Trotzdem muss der Programmierer noch viel geistige Energie in die Organisation des Suchprozesses stecken, um einen erfolgreichen Algorithmus zu schreiben.
Es wäre von Vorteil nur das potentielle Resultat zu beschreiben und sich nicht um den Prozess zur Findung dieses Ergebnisses kümmern zu müssen. So kommen wir zur deskriptiven Programmierung.
Um das zu realisieren eignen sich nichtdeterministische Algorithmen besonders gut.
Ein nichtdeterministischer Algorithmus "erahnt" den richtigen Pfad von der Wurzel bis zum Resultat-Blatt, falls eins existiert.
Nichtdeterminismus beschreibt eine übernatürliche Fähigkeit, das Richtige vorherzusehen.
Nun könnte man denken, durch den Einsatz des Nichtdeterminismus kann man auch die Effizienz des Algorithmus steigern, dass gelingt aber nur in den seltensten Fällen. Der Nichtdeterminismus wird durch deterministische Sprachmittel simuliert, im Hintergrund findet eine Tiefensuche statt, die bei vollständigem Durchlauf einen exponentiellen Aufwand erfordert.
Der große Vorteil vom Einsatz des Nichtdeterminismus ist die Verbesserung der kognitiven Effizienz, die hilft komplexere Probleme zu lösen.
Nichtdeterminismus in Scheme
Um den Nichtdeterminismus in Scheme zu nutzen benötigt man einige Befehle, die man zusätzlich implementieren muss.
choice: Nimmt eine Liste und gibt "das richtige Element" daraus zurück. Wenn der Befehl eingebettet ist, wird der Wert zurück gegeben, der zum "Erfolg des Gesamtausdrucks" führt.
bag-of: Nimmt eine Liste und gibt eine Liste der Elemente zurück, die zum Erfolg führen.
multichoice: Nimmt eine Liste ls und eine natürliche Zahl n und gibt die n "richtigen" Elemente aus ls zurück.
randomchoice: Nimmt eine natürliche Zahl n und berechnet das richtige Element aus der Liste (1 2 3 ... n).
initialize-amb-fail: Diese nullstellige Prozedur (thunk), dient zur Initialisierung des Ambigious-Systems.
Nichtdeterministische Summandensuche
Das folgende Programm sucht nach Summanden für eine angegebene ganze Zahl.
Anwendung auf das Rucksackproblem
Nun nutzen wir die nichtdeterministischen Sprachmittel um unser Rucksackproblem zu lösen.
Jetzt wird in diese Prozedur noch die Forderung nach der maximalen Gewichtssumme der eingepackten Gegenstände eingebaut.
