Post on 06-Feb-2018
Computerpraktikum zur Linearen Optimierung
10. und 11. Oktober 2013
Melanie Herzog – Lehrstuhl für Angewandte Geometrie und Diskrete Mathematik Oktober 2013
1. Einführung in Xpress-MP
• Softwarepaket zur Linearen und Gemischt-Ganzzahligen Optimierung
• Komponenten:
• Optimizer (primaler und dualer Simplex, Barrier, MIP, Presolver, Heuristiken)
• Programmier- und Modellierungssprache Mosel
• Bibliotheken zur Einbindung von Mosel in C/C++/Java/VB
• Entwicklungstools (Debugger, Profiler, IDE)
• Weitere Module (Datenzugriff, Graphik, …)
1. Einführung in Xpress-MP
Was ist Xpress-MP?
1. Einführung in Xpress-MP
Was ist Xpress-MP?
Modell
Ausgabe
Mosel Optimizer
Daten
Interaktion
Lösung
1. Einführung in Xpress-MP
Xpress IVE
Tool Bar
Project Bar
Editor Run Bar
Info Bar
Kompilieren
Kompilieren (sofern noch nicht geschehen) + Ausführen
Run Optionen
Weiter, wenn pausiert (siehe Kapitel 7)
Abbrechen („Ask Mosel/Optimizer to Stop“)
1. Einführung in Xpress-MP
Tool Bar
1. Einführung in Xpress-MP
Tool Bar
• zeigt alle Variablen, Funktionen … an
Nach einem Programmdurchlauf:
• Zeigen auf einen Variablennamen (auch im Editor) Variablenwert in einem Popup angezeigt
• Doppelklick auf einen Variablennamen Variablenwert in einem Fenster angezeigt
1. Einführung in Xpress-MP
Project Bar
• Output/Input: Ausgabe
• Stats: Statistiken zur Optimierung
• Matrix: Darstellung der Nebenbedingungsmatrix
• Solutions: bisher gefundene Lösungen
1. Einführung in Xpress-MP
Run Bar
2. Einführung in Mosel
2. Einführung in Mosel
Modellaufbau
model ModelName
options ! Optionen
uses ! optionale Bibliotheken
parameters
! optionale Parameter
end-parameters
declarations
! Variablendeklaration
end-declarations
! Programmcode
end-model
• Modell zwischen model und end-model
• jedes Modell muss einen Modellnamen haben
• ! leitet Kommentare ein
2. Einführung in Mosel
Modellaufbau
model ModelName
! ...
end-model
Beispiel:
• durch options eingeleitet
• am Modellanfang
• Vereinfachung der Fehlersuche:
• Option noimplicit : jede Variable muss deklariert werden
• Option explterm : jeder Befehl muss mit ; abgeschlossen werden
2. Einführung in Mosel
Optionen
model ModelName
options noimplicit, explterm;
! ...
end-model
Beispiel:
• durch uses eingeleitet
• am Modellanfang
• Bibliothek "mmxprs" : Xpress-Optimizer
2. Einführung in Mosel
Bibliotheken
model ModelName
options noimplicit, explterm;
uses "mmxprs";
! ...
end-model
Beispiel:
• Parameter zwischen parameters und end-parameters
• definiert Parameter, die auch nach dem Kompilieren noch gesetzt werden können
2. Einführung in Mosel
Parameter
parameters
datafile = "../data.dat";
end-parameters
Beispiel:
• Variablen müssen vor Verwendung deklariert werden
• Variablendeklaration zwischen declarations und end-declarations
• Modell kann mehr als einen Deklarationsblock enthalten
• einfache Variablentypen:
boolean true oder false
integer ganze Zahlen
real „reelle“ Zahlen
string Zeichenketten
2. Einführung in Mosel
Variablendeklaration
• Mosel-eigene Variablentypen:
mpvar Entscheidungsvariable
linctr linearer Ausdruck
• Entscheidungsvariablen sind implizit reellwertig und ≥ 0
2. Einführung in Mosel
Variablendeklaration
declarations
n: integer;
x, y: mpvar;
end-declarations
Beispiel:
im mathematischen Modell:
Implementierung:
2. Einführung in Mosel
Nebenbedingungen
2*x1 + x2 >= 3;
• Operatoren: <= , = , >=
• Nebenbedingungen können als Variablen abgespeichert werden (Zuweisung mit := ) späterer Zugriff möglich
2. Einführung in Mosel
Zielfunktion
minimize(3*x1 + 5*x2);
• auch Zielfunktionen können als Variablen abgespeichert werden
• maximize() bzw. minimize() starten die Optimierung
erst am Modellende
(Bibliothek "mmxprs" muss eingebunden werden!)
im mathematischen Modell:
Implementierung:
• Befehle write() und writeln()
• Werte der Entscheidungsvariablen und linearen Ausdrücke:
getsol(<variable>) oder <variable>.sol
• Wert der Zielfunktion: getobjval
• Formatierung der Ausgabe:
strfmt(<variable>,<i1>,<i2>)
2. Einführung in Mosel
Ausgabe
reservierte Vorkommastellen
Nachkommastellen
• model und end-model umschließen Modell
• uses zur Einbindung von Bibliotheken
• declarations und end-declarations umschließen Variablendeklaration
• maximize() und minimize() starten die Optimierung
• write() und writeln() zur Ausgabe
• getsol() gibt Lösung zurück
• getobjval gibt Zielfunktionswert zurück
2. Einführung in Mosel
Zusammenfassung
3. Variablentypen
• einfache Variablentypen:
boolean true oder false
integer ganze Zahlen
real „reelle“ Zahlen
string Zeichenketten
• Mosel-eigene Variablentypen:
mpvar Entscheidungsvariable
linctr linearer Ausdruck
3. Weitere Variablentypen
Wiederholung
3. Weitere Variablentypen
Entscheidungsvariablen
• Wertebereich von Entscheidungsvariablen:
(weitere siehe Mosel-Dokumentation)
declarations
x : mpvar;
end-declarations
x is_integer;
Beispiel:
Wertebereich
automatisch
is_binary
is_integer
is_free
• statische Mengen:
• dynamische Mengen:
• Deklaration:
• Zuweisung:
• Umwandlung in statische Menge:
• Operatoren: + (Vereinigung), - (Differenz), * (Schnitt)
3. Weitere Variablentypen
Mengen
declarations
<setname> : set of <vartype>;
end-declarations
<setname> := {<setcontent>};
finalize(<setname>);
declarations
<setname> = {<setcontent>};
end-declarations
3. Weitere Variablentypen
Mengen
! statische Menge
declarations
s1 = {1,2,3,7};
end-declarations
! dynamische Menge
declarations
s2 : set of string;
end-declarations
s2 := {"Bli", "Bla", "Blub"};
finalize(s2);
Beispiel:
• spezielle Mengen, effizientere Speichernutzung
• statische Intervalle:
• dynamische Intervalle:
• Deklaration:
• Zuweisung:
• Umwandlung in statisches Intervall:
3. Weitere Variablentypen
Intervalle
declarations
<rangename> : range;
end-declarations
<rangename> := <lb>..<ub>;
finalize(<rangename>);
declarations
<rangename> = <lb>..<ub>;
end-declarations
3. Weitere Variablentypen
Intervalle
! statisches Intervall
declarations
r1 = 3..7;
end-declarations
! dynamische Menge
declarations
r2 : range;
end-declarations
r2 := 3..7;
finalize(r2);
Beispiel:
• statische Felder:
oder:
• Deklaration:
• Zuweisung:
• Zugriff:
3. Weitere Variablentypen
Felder
<arrayname> :: (<indexset>) [<arraycontent>];
declarations
<arrayname> = [<arraycontent>];
end-declarations
declarations
<arrayname> : array(<indexset>) of <vartype>;
end-declarations
<arrayname>(<index>);
3. Weitere Variablentypen
Felder
! dynamisches Feld
declarations
s = {"Bli", "Bla", "Blub"};
A : array(s) of integer;
end-declarations
A :: (["Bla", "Blub", "Bli"]) [1,2,3];
writeln(A("Blub"));
Beispiel:
• insbesondere können Intervalle Indexsets sein vereinfachte Zuweisung :
<arrayname> :: [<arraycontent>];
! Output: 2
• dynamische Felder:
• Deklaration:
• Zellen werden erst erzeugt durch Zuweisen eines Wertes oder durch
• Test ob eine Zelle erzeugt wurde:
3. Weitere Variablentypen
Felder
declarations
<arrayname> : dynamic array(<indexset>)
of <vartype>;
end-declarations
exists(<arrayname>(<index>));
create(<arrayname>(<index>));
• mehrdimensionale Felder:
• Deklaration:
• Zuweisung:
• Zugriff:
3. Weitere Variablentypen
Mehrdimensionale Felder
declarations
<arrayname> : array(<indexset1>,<indexset2>)
of <vartype>;
declarations
<arrayname> :: (<indexset>,<indexset2>)
[<arraycontent>];
<arrayname>(<index1>,<index2>);
3. Weitere Variablentypen
Mehrdimensionale Felder
! mehrdimensionales dynamisches Feld
declarations
s = {"Bli", "Bla", "Blub"};
r = 1..2;
A : array(s,r) of integer;
end-declarations
A :: (["Bli", "Bla", "Blub"],[1,2]) [1,2,3,4,5,6];
writeln(A("Blub",1));
Beispiel:
! Output: 5
• Strukturen fassen Variablen verschiedener Variablentypen zusammen
• Deklaration:
• Zugriff auf einen Teil der Struktur: <recordname>.<varname>
• Zuweisung: jeden Teil der Struktur einzeln
3. Weitere Variablentypen
Strukturen
declarations
<recordtyp> = record
! Deklaration der Teile der Struktur
analog Deklarationsblock
<varname> : <vartype>;
end-record;
<recordname> : <recordtyp>;
end-declarations
3. Weitere Variablentypen
Strukturen
declarations
tier = record
id : integer;
tierlaut : string;
end-record;
kuh, schaf : tier;
end-declarations
kuh.id := 1; kuh.tierlaut := "Muh";
schaf.id := 2; schaf.tierlaut := "Maeh";
writeln("Das Schaf macht ", schaf.tierlaut);
Beispiel:
4. Kontrollstrukturen
• if-Anweisung:
• Bedingungen: < , <= , = , >= , > , <>, ...
• Negation: not
• Verknüpfung von Bedingungen: and, or
4. Kontrollstrukturen
if-Anweisungen
if (<condition>) then
<commands>
elif (<condition>) then ! optional
<commands>
else ! optional
<commands>
end-if
• für Fallunterscheidungen mit vielen Fällen
• testet auf Gleichheit
• case-Anweisungen:
• mehrere Anweisungen durch do … end-do einschließen
4. Kontrollstrukturen
case-Anweisungen
case <linke Seite> of
<rechte Seite 1> :
<command>
<rechte Seite 2> :
<command>
! ...
else ! optional
<commands>
end-case
• forall-Schleife:
• Vereinfachung bei nur einer Anweisung: forall (<index> in <indexset>) <command>
• Schleife über mehrere Indexmengen möglich:
effizientere Behandlung als bei Schachtelung
4. Kontrollstrukturen
forall-Schleifen
forall (<index> in <indexset>) do
<commands>
end-do
forall (<index1> in <indexset1> ,
<index2> in <indexset2> ) do
<commands>
end-do
• Bedingungen an den Schleifenindex möglich:
effizientere Behandlung als bei Schachtelung
4. Kontrollstrukturen
forall-Schleifen
forall (<index> in <indexset> | <condition>) do
<commands>
end-do
forall (i in 1..10, j in 1..100 | i^2 = j) do
writeln(j, " ist das Quadrat von ", i);
end-do
Beispiel:
• while-Schleife:
• Vereinfachung bei nur einer Anweisung: while (<condition>) <command>
• repeat-Schleife:
4. Kontrollstrukturen
while- und repeat-Schleifen
while (<condition>) do
<commands>
end-do
repeat
<commands>
until <condition>
• spezielle forall-Schleifen
• Implementierung der mathematische Summe
mittels sum(<index> in <indexset>) <command>;
• auch Summation über mehrere Indexmengen und unter Nebenbedingungen möglich
4. Kontrollstrukturen
Summen
5. Umgang mit Daten
• Modell und Daten trennen
• Daten aus Textdateien einlesen und in Textdateien ausgeben
• Dateinamen als Parameter
Dateiname kann geändert werden, ohne das Modell neu zu kompilieren
5. Umgang mit Daten
Warum?
• Daten einlesen mittels initializations from Block
• unterscheiden sich Variablenname in Modell und Datendatei:
<modellvarname> as "<datavarname>";
• Mengen, die Indexmengen von Feldern sind, werden automatisch eingelesen
5. Umgang mit Daten
Daten einlesen
initializations from "<filename>"
<varname>; ! ...
end-initializations
5. Umgang mit Daten
Daten einlesen
parameters
datafile = "daten.dat";
end-parameters
declarations
s1, s2: set of string;
a: array(s1,s2) of integer;
end-declarations
initializations from datafile
a;
end-initializations
Beispiel:
• Formatierung der Daten:
• einfache Variablentypen:
• Mengen:
• Felder:
• Elemente können durch Leerzeichen oder Komma getrennt werden
• Eingaben nicht durch ein Semikolon abschließen!
5. Umgang mit Daten
Datendatei
"<varname>" : <value>
"<setname>" : [<element1> <element2> ...]
"<arrayname>" : [(<index1>) <element1>
(<index2>) <element2> ...]
5. Umgang mit Daten
Datendatei
! Datenfile daten.dat
"s1": ["Bli", "Bla", "Blub"]
"s2": ["Muh", "Maeh"]
"a": [("Bli" ,"Muh") 1, ("Bli" ,"Maeh") 2,
("Bla" ,"Muh") 3, ("Bli" ,"Maeh") 4,
("Blub","Muh") 5, ("Blub","Maeh") 6]
Beispiel:
• Datenausgabe mittels initializations to Block
• sollen Variablen in der Datendatei unter anderem Namen gespeichert werden:
<modellvarname> as "<datavarname>";
5. Umgang mit Daten
Datenausgabe
initializations to "<filename>"
<varname>; ! ...
end-initializations
6. Benutzergraph
• zur graphischen Veranschaulichung der Lösung
• einzubindende Bibliothek: "mmive"
funktioniert natürlich nur in der IVE
• es ist nur ein einziger Benutzergraph möglich aber: in den Graphen kann in mehreren Ebenen gezeichnet werden
• Ausgabe des Benutzergraphen in der „Run Bar“, Registerkarte „User graph“
6. Benutzergraph
Grundlagen
• speichere jede Ebene als Variable ab
um die graphischen Elemente (Punkte, Linien, ...) den einzelnen Ebenen zuordnen zu können
• Erstellen einer neuen Ebene:
• alle Elemente einer Ebene haben dieselbe Farbe
• Farben: IVE_BLACK, IVE_BLUE, IVE_GREEN, usw. oder Funktion IVE_RGB()
6. Benutzergraph
Ebenen
declarations
<plotvarname> : integer;
end-declarations
<plotvarname> := IVEaddplot("<plotlabel>",<color>);
• Beschriftung:
• Punkt:
• Linie:
• Pfeil:
6. Benutzergraph
Elemente
IVEdrawpoint(<plotvarname>,<x>,<y>);
IVEdrawlabel(<plotvarname>,<x>,<y>,<text>);
IVEdrawline(<plotvarname>,<x1>,<y1>,
<x2>,<y2>);
IVEdrawarrow(<plotvarname>,<x1>,<y1>,
<x2>,<y2>);
7. Ablaufkontrolle
• einzubindende Bibliothek: "mmxprs"
• liefert den Lösungsstatus:
7. Ablaufkontrolle
getprobstat
declarations
status : string;
end-declarations
case getprobstat of
XPRS_OPT: status := "Optimum found";
XPRS_UNF: status := "Unfinished";
XPRS_INF: status := "Infeasible";
XPRS_UNB: status := "Unbounded";
XPRS_OTH: status := "Failed";
else status := "???";
end-case
• einzubindende Bibliothek: "mmive"
• pausieren:
7. Ablaufkontrolle
IVEpause
IVEpause("<Nachricht>")
8. Noch ein paar Worte zum Modellieren mit Mosel
• Nebenbedingungen werden wie folgt gespeichert:
• Erhöhung der Konstante um eins:
• Erhöhung eines Koeffizienten um eins:
8. Noch ein paar Worte …
Nebenbedingungen
Zuweisung wird gespeichert als
lc := x + y >= 1 lc := x + y – 1 >= 0
lc := 1 <= x + y lc := - x - y + 1 <= 0
Zuweisung Änderung
lc := x + y >= 1 lc -= 1
lc := 1 <= x + y lc += 1
Zuweisung Änderung
lc := x + y >= 1 lc += x
lc := 1 <= x + y lc -= x
• beliebige Änderungen:
• „Löschen“ einer Nebenbedingung:
8. Noch ein paar Worte …
Nebenbedingungen
! Konstante
getcoeff(<linctr>)
setcoeff(<linctr>,<wert>)
! Koeffizienten der Variablen
getcoeff(<linctr>,<mpvar>)
setcoeff(<linctr>,<mpvar>,<wert>)
settype(<linctr>,CT_UNB)
• Verwalten mehrere Optimierungsprobleme in einem Modell
• mosel-eigener Variablentyp: mpproblem
• Wechseln zwischen Problemen:
• Variablen und Nebenbedingungen müssen allerdings außerhalb deklariert werden (werden aber vom Presolver gelöscht, wenn sie im Modell nicht vorkommen)
8. Noch ein paar Worte …
Optimierungsprobleme
with myprob do
! Anweisungen
end-do