From d43cd9e54801d0dd23a0bca4c4299795db539e80 Mon Sep 17 00:00:00 2001 From: Erich Eckner Date: Wed, 19 Dec 2018 13:59:42 +0100 Subject: optimierung.pas: Grenzen für Parameter umgesetzt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- optimierung.pas | 80 ++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 62 insertions(+), 18 deletions(-) diff --git a/optimierung.pas b/optimierung.pas index 5c8e91e..dd3ef2b 100644 --- a/optimierung.pas +++ b/optimierung.pas @@ -11,6 +11,7 @@ type tParameterBuffer = class(tObject) function abstandsQuadrat(const params: tExtendedArray): extended; virtual; abstract; function aktiviereWeitereParameter(const params: tExtendedArray; out neu,neuD: tExtendedArray): boolean; virtual; abstract; + function schrittZuGrosz(const params,schritt: tExtendedArray): boolean; virtual; abstract; end; tOptimierer = class(tObject) @@ -35,7 +36,7 @@ type bester,schlechtester: longint; function rPar(i: longint): extended; override; function rAbst: extended; override; - function simplexSchritt(wer: longint; wieWeit: extended): extended; inline; + procedure simplexSchritt(wer: longint; wieWeit: extended; var schritt: tExtendedArray; var schrittLaenge: extended); inline; procedure ermittleRaenge(schlechtesten, besten: boolean); inline; public constructor create(buffer: tParameterBuffer; startParams,dStartParams: tExtendedArray); @@ -64,11 +65,10 @@ type procedure initOffset(offset: extended); function aktiviereWeitereParameter(const params: tExtendedArray; out neu,neuD: tExtendedArray): boolean; override; function abstandsQuadrat(const params: tExtendedArray): extended; override; + function schrittZuGrosz(const params,schritt: tExtendedArray): boolean; override; end; - // TODOs: -// - Grenzen für Parameter // - einstellbare Schrittlängenfaktoren implementation @@ -97,18 +97,19 @@ begin result:=absts[bester]; end; -function tDownHillSimplexOptimierer.simplexSchritt(wer: longint; wieWeit: extended): extended; +procedure tDownHillSimplexOptimierer.simplexSchritt(wer: longint; wieWeit: extended; var schritt: tExtendedArray; var schrittLaenge: extended); var i,j: longint; tmp: extended; begin // neu - Schwerpunkt = wieWeit * (Schwerpunkt - alt) => wieWeit = 1 <=> Spiegelung - result:=0; + schrittLaenge:=0; for i:=0 to dim-1 do begin tmp:=0; for j:=0 to dim do if j<>wer then tmp:=tmp+pars[j,i]; - result:=result + sqr((1 + wieWeit) * (tmp/dim - pars[wer,i])); + schritt[i]:= (1 + wieWeit) * (tmp/dim - pars[wer,i]); + schrittLaenge:=schrittLaenge + sqr(schritt[i]); pars[wer,i]:=tmp * (1 + wieWeit)/dim - wieWeit * pars[wer,i]; end; end; @@ -161,9 +162,9 @@ end; function tDownHillSimplexOptimierer.optimiere(minVerbesserung, minSchritt: extended; maxSchritte: int64): int64; var - schritt,verbesserung,tmp: extended; - i,j,altDim: longint; - neu,neuD: tExtendedArray; + schrittLaenge,verbesserung,tmp: extended; + i,j,altDim: longint; + neu,neuD,schritt: tExtendedArray; begin if (minVerbesserung<=0) and (minSchritt<=0) and (maxSchritte<=0) then fehler('tDownHillSimplexOptimierer.optimiere benötigt ein Abbruchkriterium!'); @@ -171,29 +172,33 @@ begin if minSchritt>0 then minSchritt:=sqr(minSchritt); + setLength(schritt,dim); + for i:=0 to dim-1 do + schritt[i]:=0; + schrittLaenge:=0; result:=0; verbesserung:=0; repeat repeat inc(result); - schritt:=simplexSchritt(schlechtester,1); + simplexSchritt(schlechtester,1,schritt,schrittLaenge); tmp:=absts[schlechtester]; absts[schlechtester]:=buf.abstandsQuadrat(pars[schlechtester]); verbesserung:=tmp - absts[schlechtester]; if absts[schlechtester] < absts[bester] then begin // ist jetzt der beste - // => wir gehen noch weiter in dieser Richtung - simplexSchritt(schlechtester,-3); - schritt:=schritt * sqr(2); // statt von -1 zu 1 sind wir von -1 zu 3 gelaufen => Faktor 2 - absts[schlechtester]:=buf.abstandsQuadrat(pars[schlechtester]); - verbesserung:=tmp - absts[schlechtester]; + if not buf.schrittZuGrosz(pars[schlechtester],schritt) then begin + // => wir gehen noch etwas weiter in dieser Richtung + simplexSchritt(schlechtester,-1.1,schritt,schrittLaenge); + absts[schlechtester]:=buf.abstandsQuadrat(pars[schlechtester]); + verbesserung:=tmp - absts[schlechtester]; + end; ermittleRaenge(true,true); continue; end; if verbesserung < 0 then begin // verschlechtert // => wir gehen einen kleineren Schritt - simplexSchritt(schlechtester,-0.5); - schritt:=schritt * sqr(3/4); // statt von -1 zu 1 sind wir von -1 zu 0.5 gelaufen => Faktor 3/4 + simplexSchritt(schlechtester,-0.5,schritt,schrittLaenge); absts[schlechtester]:=buf.abstandsQuadrat(pars[schlechtester]); verbesserung:=tmp - absts[schlechtester]; ermittleRaenge(true,false); @@ -203,7 +208,7 @@ begin until ((maxSchritte>0) and (result>=maxSchritte)) or ((minVerbesserung>0) and (verbesserung0) and (schritt0) and (schrittLaenge abs(params[p_l*i + xx_i])) or + (abs(schritt[p_l*i + yy_i]*2) > abs(params[p_l*i + yy_i])) or + (abs(schritt[p_l*i + x0_i]*2) > sXSteps) or + (abs(schritt[p_l*i + y0_i]*2) > sTSiz) or + (abs(schritt[p_l*i + a_i]) > pi/10) or + (abs(schritt[p_l*i + e_i]) > 1) then + exit; + result:=false; +end; + end. -- cgit v1.2.3-54-g00ecf