Code: Select all
draft
Code: Select all
heel
Dies ist im Grunde ein mathematisches Optimierungsproblem, daher verwende ich die NLopt-Bibliothek (insbesondere NLoptNet, da es sich um ein C#-Projekt handelt). Es gibt drei Steuerparameter (Tiefgang, Krängung und Trimm) und drei zu minimierende Ziele (
Code: Select all
netUpwardForce
Hier ist der Code:
Code: Select all
double OptimizeFunc(double[] parameters) //parameters: Draft, heel and trim
{
Model.SetPosition(parameters[0], parameters[1], parameters[2]);
List forces = new(){ Model.GetBuoyantForce(), Model.GetWeightForce() };
StabilityData stabilityData = StabilityCalculator.Calculate(forces); //calculates net upward force, heeling moment and trimming moment
double netUpForceComp = Math.Abs(stabilityData.NetUpwardForce / Model.GetMaximumTheoreticalBuoyancyForce());
double heelMomComp = Math.Abs(stabilityData.HeelingMoment / Model.GetMaximumTheoreticalHeelingMoment());
double trimMomComp = Math.Abs(stabilityData.TrimmingMoment / Model.GetMaximumTheoreticalTrimmingMoment()));
double total = netUpForComp + heelMomComp + trimMomComp;
return total;
}
var parameters = { 0, 0, 0 } ;
using (solver = new NLoptSolver(NLoptAlgorithm.LN_BOBYQA, (uint)parameters.Count))
{
solver.SetLowerBounds(new double[] {0, -180 , -90});
solver.SetUpperBounds(new double[] {Model.GetModelHeight(), 180 , 90});
solver.SetMinObjective(OptimizeFunc);
var nLoptResult = solver.Optimize(new double[] {0, 0 , 0}, out var finalScore);
Debug.Print(finalScore)
}

< /p>
Auch wenn der Löser glaubt, ein lokales Minimum gefunden zu haben, weiß ich durch manuelles Anpassen der Werte für Tiefgang, Ferse und Trimm, dass die tatsächlich beste Lösung Tiefgang = 0,202 ist, Heel = 0, Trim = -0.32, was zu einem Score = 0.001 führt (und es könnte noch weiter verfeinert werden, aber ich habe dort aufgehört). Wie Sie der Grafik entnehmen können, erreicht der Löser unterdessen nur einen Wert von 0,013, was nicht einmal nahe kommt. Ich habe zusätzliche Tests durchgeführt, um den gesamten Optimierungsbereich abzubilden, und bestätigt, dass es außer diesem keine weiteren Mindestwerte gibt. Ich habe auch versucht, die Grenzen sehr nahe an diesem bekannten Minimum einzuschränken, aber der Löser kann es immer noch nicht finden.
Ich vermute, dass das Problem an HeelingMoment und TrimmingMoment reagieren sehr empfindlich darauf, dass NetUpwardForce nicht Null ist, daher habe ich versucht, Gewichtungsfaktoren hinzuzufügen, damit der Optimierer zuerst die Minimierung von NetUpwardForce priorisiert, aber das hilft nicht weiter. Ich habe auch versucht, die Optimierung für HeelingMoment und TrimmingMoment zu verwerfen und stattdessen den Optimierer so einzustellen, dass die horizontalen Abstände zwischen den Auftriebs- und Gewichtskraftzentren minimiert werden, aber auch das hat nicht geholfen. Ich habe auch versucht, netUpForComp, HeelMomComp und trimMomComp auf höhere Potenzen zu erhöhen, und das hat ein wenig geholfen, löst das Problem aber immer noch nicht.
Kann jemand, der Erfahrung mit mathematischer Optimierung hat, vorschlagen, was an meinem Ansatz falsch sein könnte? Ist es die Art und Weise, wie ich die Gesamtsumme in OptimizeFunc berechne? Oder sollte ich anstelle von BOBYQA einen anderen Algorithmus verwenden? Ich habe mehrere ausprobiert, aber keines hat zu besseren Ergebnissen geführt.
BEARBEITEN: Zusätzliches Detail: Wenn ich die richtigen Lösungsparameter übergebe (
Code: Select all
draft = 0.202