ich optimiere gerade mit fmincon und würde meinen Solver gerne verbessern und beschleunigen.
Mal kurz das (vereinfachte)Problem umrissen:
Die gesuchten X-Werte sind Veränderungen in der Leistungen und liegen zwischen -XY und +XY. (rauf- und runterfahren).
Als Nebenbedingung sollen an manchen Stellen rauf und an manchen Stellen runtergefahren werden um andere Werte Y einzuhalten. Diese Nebenbedingungen sind über eine Sensitivitätsmatrix S verknüpft. Hier kann der Wert von X aber je nach dem positiv oder negativ sein.
S*X < Y
Meine Zielfunktion sind die Absolutwerte von X, da so wenig wie möglich verändert werden soll aber dies negativ oder positiv sein kann. Deswegen verwende ich fmincon. Vorher konnte ich es noch linear machen mit einer Fallunterscheidung. Das geht jetzt aber nicht mehr.
Fmincon funktioniert, ist aber verglichen mit einem linearen Problem natürlich langsamer.
Ich habe bereits den Algorithmus auf "sqp" gestellt, das bringt schon ein bisschen was. Gibt es da noch andere Möglichkeiten?
Gleichfalls bricht er öfters ab (obwohl die Nebenbedingungen nicht erfüllt sind), da die Schrittweite unter X-Tol liegt.
fmincon stopped because the size of the current step is less than
the selected value of the step size tolerance but constraints are not
satisfied to within the selected value of the constraint tolerance.
Eigentlich müssen die X-Toleranzen gar nicht so groß sein, aber sonst bricht er mir vorher schon ab. Kann ich das verhindern?
Ich weiß, dass das Thema "richtige Einstellungen" bei einem Optimierer extrem wichtig sind. Vielleicht kann mir da jemand den ein oder anderen Tipp geben.
PS: Ach ja und mir geht es wirklich um allgemeinere Sachen innerhalb dieses Themas, das aktuelle Skript verändert sich gerade laufend und ist sehr lang und komplexer.
ich habe mich auch länger mit der Beschleunigung von Matlab Code beschäftigt. Neben einigen Anpassungen direkt im Code, also z.B. durch Preallocation, ... brachte mir das konvertieren der Zielfunktion in ein Mex-File den größten Beschleunigungsboost. Mit "Coder" konvertiest du deine Zielfunktion in ein Mex-File und ruft das dann anstelle der Matlab-Funktion auf, z.b.
minFunc(x,y) --> minFunc_mex(x,y)
Hey, also der Coder scheint bei mir nicht installiert zu sein. Das Quadrat bringt ein bisschen was aber noch nicht viel.
Der Code ist deutlich komplizierter als dargestellt.
Ich habe für 216 Stellen jeweils drei Beschränkungen, d.h. meine Sensitivität S ist eine große Matrix. Die x0-Werte liegen bei mir bei 0, da ich das genauer nicht sagen kann (ca. von -100 bis +100).
Wie lange ist denn "lange"?
Müssen mehrere Optimierungen ausgeführt werden? Falls ja, kann vielleicht das Ergebnis einer Optimierung als Startwert für die nächste verwendet werden?
Zudem kann man auch mal andere Solver versuchen. Mit der von Friiday vorgeschlagenen angepassten Zielfunktion wäre das ein Fall für
lsqlin
.
Man kann auch mal, sofern die Global Optimization Toolbox vorhanden ist,
patternsearch
versuchen.
Ok, dann hier mal ein paar Codeschnipsel aber ich sage gleich: schön und übersichtlich ist das nicht .
Ich habe mal den Workspace in eine Datei gepackt und hoffe, dass das geht. Ich habe mal die Grenzen noch auf 0 gesetzt, an der Stelle, ab der sich da definitiv nichts ändern kann (erste Hälfte).
Der gesuchte Vektor sind Änderungen in der Leistung, Opt.x. Diese sind möglichst klein zu halten.
Zu den Grenzen: AA*x < bA muss eingehalten werden, alles unter dem Grenzwert data.imax, AA ist die Sensitivitätsmatrix
Aeq: in dem Fall werden alle Änderungen addiert
beq: und die sollen einen bestimmten Wert ergeben (an der Stelle 0)
data.Ba, PVA, usw. sind die Leistungen an den Stellen für Biomasseanlagen, PV-Anlagen, usw.
fun: Die gesamte Veränderung soll möglichst klein sein. Vorher wurde schon was verändert, deswegen wird diese mit dazu gezählt (kann sich ja wieder aufheben).
die Zahlen vor der Summe ist die Priorität, welche Anlagen zuerst genommen werden sollen.
Und hier ist der Knackpunkt. Um ein möglichst genaues Ergebnis zu bekommen, muss ich die entweder seeehr unterschiedlich machen (z.B. 10er-Potenzen) oder die Toleranz sehr klein machen. Beides kostet extrem viel Zeit. Ich will natürlich ein möglichst genaues Ergebnis, z.B. die WaA (Wasserkraftanlagen) sollen nur im Notfall benutzt werden.
Was ist hier sinnvoller???
An der Stelle kommt jetzt mein Optimierungscode:
Code:
bA = data.imax - Aus(:,iter)-5;
Aeq = [zeros(1,data.EinsNr), ones(1,data.EinsNr)];
x0 = zeros(2*data.EinsNr, 1);
AA = [zeros(size(SMA)),SMA];
Bisher ist es eben so, dass mir das Ergebnis zu ungenau ist. Wenn ich aber aber die Prioritäten oder die Genauigkeit zu stark einstelle, dauert die Berechnung sehr lange.
Ach ja, und TolX ist so hoch, weil er sonst manchmal mitten in der Berechnung abbricht. Hatte ich weiter oben ja schon geschrieben.
zu 12:19
Die einzige Möglichkeit, einige Parameter zunächst konstant zu lassen, sehe ich in folgender Vorgehensweise:
x1 = fmincon(..., x0, ...) % erste Optimierung mit wenigen Parametern
x2 = fmincon(..., x1, ...) % Optimierung aller Parameter mit vorherigem Ergebnis als Startwert
Natürlich kann man das auch weiter schachteln.
zu 16:22
Problem bei abs: nicht differenzierbar, insofern ist fmincon bei um die 0 schwankenden Einträgen schlecht geeignet.
Mit anderen Worten: Da kann man eigentlich gar nicht viel machen außer entweder eine andere Zielfunktion zu nehmen oder die Zeit eben einzuplanen!?
Na gut, danke mal trotzdem!
Ein Beispiel hatte ich ja gepostet. Ich habe jetzt für die Anfangswerte davor noch eine lineare Optimierung machen können und komme nun mit ausreichender Genauigkeit auf 10-80 s pro Optimierung. Ist ok...
Falls mehrere Optimierungen ausgeführt werden müssen, kann man bei ähnlichen Szenarien häufig das Ergebnis einer Optimierung als Startwert für die nächste verwenden.
Ja, das mit den Nullen habe ich an der Stelle auch rausgekickt. Der erste Teil fliegt raus. Hat allerdings zeitmäßig gar keinen sooo großen Vorteil gebracht.
Das Ergebnis als neuer Startwert wird schon gemacht.
Ich weiß aber auch echt nicht, ob man da jetzt noch viel rausholen kann von der Geschwindigkeit.
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.