Fallbeispiel


... [ Seminar "Programmierkonzepte und Programmiersprachen" ] ... [ Inhaltsverzeichnis ] ... [ zurück ] ... ... [ weiter ] ...

Übersicht: Fallbeispiel


Einleitung

Anhand dieses Beispieles soll dem Leser ansatzweise vermittelt werden, wie mächtig die logische Programmierung mit Einschränkungen ist. Sicher kann dies nach diesem einfachen Beispiel auch weiterhin nur erahnt werden, doch wird hier deutlich, wie man ein kombinatorisches Problem mittels der vorgestellten Technik lösen kann.

Auch wird hier eine Art der Ausgabe vorgestellt, die es ermöglicht, die Ergebnisse sofort abzulesen, ohne jegliche Zuordnungen im nachhinein treffen zu müssen.


Aufgabenstellung

Wenn im schönen Golfclub zu Wedel mal wieder keine Mitglieder auf dem Parcours ihr Können versuchen, dürfen die Angestellten außerhalb ihrer Arbeitszeit eine Runde Golf spielen.

Kürzlich spielten also Timo und drei andere Angestellte eine 18 Loch Runde auf dem Platz. Zum Abschluss gingen alle vier - einschließlich Herrn Becker - zum Clubhaus, um ihrer Ergebnisse zusammenzurechnen. Jeder der vier hat einen anderen Beruf (einer ist Koch) und jeder erzielte ein anderes Ergebnis auf der Runde. Niemand benötigte weniger als 70 Schläge oder mehr als 85. Ist es möglich aus folgenden Hinweisen von jedem Angestellten den vollen Namen, seinen Beruf und seine Schläge zu ermitteln?

  1. Sven, der nicht der Gärtner ist, spielt oft Golf und hat die niedrigste Runde aller gespielt.
  2. Herr Budde, der nicht Ole heißt, schlug mehrere Bälle in den Wald und hat daher 10 Schläge mehr benötigt, als der Shop-Verkäufer.
  3. In unbestimmter Reihenfolge haben Klaus und der Caddy vier und 7 Schläge mehr benötigt als Herr Mueller.
  4. Herr Krug denkt, dass seine 78 Schläge eins der besseren Spiele waren, auch wenn Klaus weniger Schläge benötigt hat.
  5. Keiner der vier benötigte genau 81 Schläge.

Lösung

Wie beschrieben, lassen sich mittels der fd-Bibliothek in ECLiPSe numerische Probleme lösen. Daher erfolgt in diesem Fall der Ansatz, dass jeder Vorname, jeder Nachname und jeder Beruf eine Variable repräsentiert, die die von der Person jeweils benötigte Anzahl an Schlägen aufnimmt. Ist dies bewusst, können jeweils drei Listen definiert werden, die jeweils alle Variablen der Vornamen, der Nachnamen und der Berufe beinhalten.
VN = [Sven, Ole, Klaus, Timo],
NN = [Budde, Krug, Mueller, Becker],
Jobs = [Gaertner, Caddy, Verkaeufer, Koch],

Diesen Listen lässt sich durch die Aufgabenstellung als Domain sehr schnell ein Integerintervall von 70 bis 85 zuweisen, welches allerdings aufgrund des fünften Hinweises den Wert 81 ausschließt.
VN :: [70..80,82..85],
NN ::[70..80,82..85],
Jobs :: [70..80, 82..85],

Aufgrund der Aussage, dass alle Spieler ein unterschiedliches Ergebnis erzielten, kann festgestellt werden, dass alle Variablen einer Liste unterschiedliche Werte annehmen müssen. Dies erreichen wir, indem wir die alldifferent-Regel der fd-Bibliothek anwenden.
alldifferent(VN),
alldifferent(NN),
alldifferent(Jobs),

Um eine komfortable Ausgabe zu ermöglichen, bei der keine nachträgliche Zuordnung einzelner Werte zueinander über Zahlen erfolgen muss, wird hier kurz ein Konzept vorgestellt, welches mit sogenannten Units arbeitet. Hierbei werden zwei Listen definiert, deren Elemente (unit) die gleiche Struktur haben. Ein Element besteht aus Schlägen, Vorname, Nachname und Beruf.
Die erste Liste namens Units enthält genau vier Elemente - wir haben vier Spieler - mit der beschriebenen Struktur. Alle Variablen darin sind anonym, dass heißt, sie enthalten noch keine Werte.
Units = [
unit(_,_,_,_),
unit(_,_,_,_),
unit(_,_,_,_),
unit(_,_,_,_)],

Die zweite Liste namens Constraints verknüpft die oben eingeführten Variablen mit den zum jetzigen Zeitpunkt bekannten Werten, nämlich den Vornamen, Namen und Berufen. Wie bereits erwähnt haben die Elemente dieser Liste die gleiche Struktur wie die Elemente in der Liste Units.
Constraints = [
unit(Sven, sven, _,_),
unit(Ole, ole, _,_),
unit(Klaus, klaus,_,_),
unit(Timo, timo, _,_),

unit(Budde, _, budde, _),
unit(Krug, _, krug,_),
unit(Mueller, _, mueller, _),
unit(Becker, _, becker, _),

unit(Gaertner, _,_,gaertner),
unit(Caddy, _,_,caddy),
unit(Verkaeufer, _,_,verkaeufer),
unit(Koch, _,_,koch)],

Im nächsten Schritt werden die Einschränkungen, welche sich aus den fünf Hinweisen herleiten lassen, definiert.
Sven ## Gaertner,
Sven #< Ole,
Sven #< Klaus,
Sven #< Timo,
Budde ## Ole,
Budde #= Verkaeufer + 10,
(Klaus #= Mueller + 7, Caddy #= Mueller + 4;
Klaus #= Mueller + 4, Caddy #= Mueller + 7),
Krug #= 78,
Klaus #< Krug,

Zum Abschluss wird die Regel "psubset" aufgerufen, welche den Elementen in der Liste Units die Werte zuweist. Dies geschieht indem nach der Auswertung der Bedingungen überprüft wird, ob die Elemente der Liste Constraints in der Liste Units enthalten sind. Dies ist der Fall, wenn die Anzahl der Schläge identisch ist und die im Element der Liste Constraints belegte weitere Variable in der Liste Units noch nicht belegt, also anonym ist. Sollte dies nicht der Fall sein, erfolgt ein Rückschritt gemäß des Backtrackingalgorithmus. Auf diese Weise wird die komplette Liste Constraints abgearbeitet.

Dem interessierten Leser sei an dieser Stelle auch der komplette Quelltext zur Verfügung gestellt.

Als Lösung erhält man:

Schläge Vorname Nachname Beruf
71 Sven Mueller Koch
78 Ole Krug Caddy
75 Klaus Becker Verkaeufer
85 Timo Budde Gaertner

... [ Seminar "Programmierkonzepte und Programmiersprachen" ] ... [ Inhaltsverzeichnis ] ... [ zurück ] ... ... [ weiter ] ...