6.3.2. Branch and Bound
Das Branch-and-Bound-Konzept sieht vor, dass bei der Generierung einer Lösung für
ein Problem, das Nebenbedingungen beeinhaltet, Kosten für jede Nebenbedingung, die
nicht eingehalten wird, entstehen. Wenn eine erste Lösung gefunden worden ist, dann wird
eine weitere Lösung durch Modifikation der ersten Lösung generiert, die weniger Kosten
verursachen muss als die Erste. So wird auf Grundlage einer alten Lösung jeweils eine
neue bessere generiert, solange bis keine kostengünstigere Lösung mehr gefunden
werden kann.
Im Zusammenhang mit dem Stundenplanproblem werden für jede Problemvariable in der labeling-Phase
mit findall alle weichen Constraints, die diese Veranstaltung betreffen, aus der Wissensbasis gesucht
und die dort angegebenen Vorgaben mit den gerade für Raum Tag und Zeit gesetzten Werte
verglichen.
Stimmen die tatsächlichen Werte nicht mit den Vorgaben der weichen Constraints überein,
so entstehen Kosten in Abhängigkeit der Priorität der Constraints.
Die Kosten, die durch eine Auswahl einer Wertekombination für die Domain-Variablen Raum,
Tag und Zeit entstehen, werden mit Hilfe des in der FiniteDomain Library vorgegebenen Constraints
minimize minimiert. Dadurch wird eine Werteauswahl erzwungen, die der optimalen Erfüllung
der Constraints für diese Veranstaltung am nächsten kommt.
Es werden also mit indomain solange Wertebelegungen durchgeführt (wobei natürlich die
auch die bereits beschriebenen Heuristiken verwendet werden können ), bis die Kosten, welche über
die Wertebelegung und die mit der Problemvariablen verbundenen Constraints berechnet werden,
minimal sind. (vgl. [1])
Beispiel:
Auszug aus der Wissensbasis
...
veranstaltungamum(analysis1_1, 2, 3, 10).
veranstaltungamum(bwl_1, 1, 1, 5).
...
Auszug aus dem Programm
labeling([]).
labeling([PVar|PVRest]) :-
minimize(wertebelegung(PVar, Kosten), Kosten),
labeling(PVRest).
wertbelegung(PVar, Kosten) :-
PVar = raumTagZeit(Raum, Tag, Zeit, VeranstaltungsID),
% veranstaltung am um
findall(bevTermin(BTag, BZeit, Prio), veranstaltungamum(VerID, BTag, BZeit, Prio),
BTerminListe),
verarbeite_veramum(Tag, Zeit, BTerminListe, Kosten).
verarbeite_veramum(_, _, [], 0).
verarbeite_veramum(Tag, Zeit, [BevTermin|BTRest], Kosten) :-
BevTermin = bevTermin(BTag, BZeit, Prio),
(BTag =/= Tag; BZeit =/= Zeit),
Kosten0 is Prio,
verarbeite_veramum(Tag, Zeit, BTRest, KostenNew),
Kosten is Kosten0 + KostenNew.
verarbeite_veramum(Tag, Zeit, [BevTermin|BTRest], Kosten) :-
verarbeite_veramum(Tag, Zeit, BTRest, Kosten).