2016-04-19 12 views
1

Ich führe ein nichtlineares Optimierungsproblem in OpenMDAO, von dem ich die optimale Lösung kenne (ich möchte nur die Lösung überprüfen). Ich verwende SLSQP Treiberkonfiguration von ScipyOptimizer von openmdao.api.ScipyOptimizer gibt ein falsches Optimierungsergebnis

Ich habe 3 Entwurfsvariablen A, B und C, die jeweiligen Design-Räume (A min bis A max für A und so weiter) und eine einzige Zielfunktion Z. Wie gesagt, ich kenne die optimale Werte für alle drei Konstruktionsvariablen (lassen sie sie nennen A sol, B sol und C Sol), die den Mindestwert von Z erhalten wurde (es sol Z nennen).

Wenn ich dieses Problem ausführen, bekomme ich einen Wert für Z, die größer ist als Z Sol, was bedeutet, dass es keine optimale Lösung ist. Wenn ich C Sol zu C zuweisen und das Problem mit nur A und B als Entwurfsvariablen ausführen, bekomme ich den Wert von Z, der viel näher an Z sol ist und das ist tatsächlich kleiner als das, was ich früher (in 3 Entwurfsvariables Szenario).

Warum beobachte ich dieses Verhalten? Sollte nicht ScipyOptimizer die gleiche Lösung in beiden Fällen geben?

EDIT: einige Code Hinzufügen ..

from openmdao.api import IndepVarComp, Group, Problem 
from openmdao.api import ScipyOptimizer 

class RootGroup(Group): 
    def __init__(self): 
     super(RootGroup, self).__init__() 

     self.add('desvar_f', IndepVarComp('f', 0.08)) 
     self.add('desvar_twc', IndepVarComp('tool_wear_compensation', 0.06)) 
     self.add('desvar_V', IndepVarComp('V', 32.0)) 
     # Some more config (adding components, connections etc.) 

class TurningProblem_singlepart(Problem): 
    def __init__(self): 
     super(TurningProblem_singlepart, self).__init__() 

     self.root = RootGroup() 

     self.driver = ScipyOptimizer() 
     self.driver.options['optimizer'] = 'SLSQP' 

     self.driver.add_desvar('desvar_f.f', lower=0.08, upper=0.28) 
     self.driver.add_desvar('desvar_twc.tool_wear_compensation', lower=0.0, upper=0.5) 
     self.driver.add_desvar('desvar_V.V', lower=32.0, upper=70.0) 
     self.driver.add_objective('Inverse_inst.comp_output') 
     # Other config 

Dieser Code gibt mir falsches Ergebnis. Wenn ich desvar_twc aus den beiden Klassen entferne und es mit seinem optimalen Wert (aus der Lösung, die ich habe) zugebe, erhalte ich ein ziemlich korrektes Ergebnis, d. H. Die Antwort für die Zielfunktion, die kleiner ist als das vorherige Szenario.

+0

Können Sie uns einen Code zeigen? –

+1

Ja, ich füge Code-Schnipsel zusammen, um es klarer zu machen. Der eigentliche Code ist viel größer, deshalb habe ich ihn nicht in die Post gesetzt. Ich werde den Beitrag in Kürze bearbeiten. –

+1

Super! Das geht immer ein langer Weg :) –

Antwort

0

Ohne Ihr aktuelles Modell zu sehen, können wir nichts sicher sagen. Es ist jedoch NICHT der Fall, dass eine Lösung des lokalen Optimierers im Allgemeinen unabhängig von der Startbedingung ist. Das ist nur der Fall, wenn das Problem konvex ist. Ich würde also annehmen, dass Ihr Problem nicht konvex ist und Sie in lokale Optima geraten.

Sie können versuchen, dies zu umgehen, indem Sie den COBYLA-Optimierer anstelle von SLSQP verwenden, was nach meiner Erfahrung es schafft, einige lokale Optima besser zu überspringen. Aber wenn Ihr Problem wirklich holprig ist, würde ich Ihnen vorschlagen, von der pyopt-sparse library zu NSGA-II oder ALPSO zu wechseln. Dies sind heuristisch basierte Optimierer, die den "größten Hügel" gut finden, obwohl sie nicht immer den ganzen Weg bis zum Gipfel hinaufsteigen (sie konvergieren nicht so eng). Die heuristischen Algorithmen sind im Allgemeinen auch teurer als die gradientenbasierten Verfahren.

+0

Danke für die Hinweise. Ich versuche gerade, das Problem mit COBYLA zu lösen und werde die Post mit den Ergebnissen aktualisieren. Das einzige, worüber ich verwirrt war, war 'desvar_twc = 0,05 ', was die optimale Lösung ist, der Optimierer gab mir 0,00 als den optimalen Wert, selbst wenn ich ihn mit 0,06 initialisierte. Was fehlt mir hier? –

Verwandte Themen