Funktionswerte durch Schleifen ermitteln, ander Ansatz?

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Hartkern
Beiträge: 69
Registriert: Sa 5. Dez 2015, 20:03
OS, Lazarus, FPC: Win10 IDE 1.6
CPU-Target: 64Bit
Wohnort: Leipzig

Funktionswerte durch Schleifen ermitteln, ander Ansatz?

Beitrag von Hartkern »

Hallo,

ich hab mit Hilfe der Jacobi Iteration eine Lineare Gleichung mit 7 Unbekannten ermittelt. Die Formel ermittelt die Endgeschwindigkeit eines Fahrzeugs in einem Rennspiel auf der XBoxOne, in Abhängigkeit von Achsübersetzung und 1. bis 6. Gang.
Ich suche Funktionswerte die oberhalb von 437 km/h sind. Gibts ne schnelle mathematische Lösung dafür (weil Extremwerte mit 7 unbekannten hat ich nicht im ABI :oops: )
Ansonsten hab ich bisher als Ansatz folgenden Code der fast sämtlichen Variationen durchprobiert. Jedoch hab ich die starke Vermutung das ich meine gewünschten Werte erst am Sankt Nimmerleinstag erhalten werden.

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var
  i,j,k,l,m,n,o: Integer;
  aErgebnis : array of real;
  Str: TStringList;
  Ergebnis: Real;
 
begin
  Str := TStringList.Create;
  setlength(aErgebnis,7);
 
  setlength(aFormel,7);
  aFormel[0]:=-28.1715;
  aFormel[1]:=-851.4926;
  aFormel[2]:=3510.4918;
  aFormel[3]:=-2851.2353;
  aFormel[4]:=1522.963;
  aFormel[5]:=-1322.963;
  aFormel[6]:=-460;
 
  setlength(aWerte,7,4);
  //Achsübersetzung
  aWerte[0,0]:=6.10; //MaxWert
  aWerte[0,1]:=2.20; //MinWert
  aWerte[0,2]:=0.01; //Schrittfaktor
  aWerte[0,3]:=(aWerte[0,0]-aWerte[0,1])/aWerte[0,2];   //Maximale Anzahl der Möglichkeiten
  //1. Gang
  aWerte[1,0]:=6.00; //MaxWert
  aWerte[1,1]:=0.48; //MinWert
  aWerte[1,2]:=0.01; //Schrittfaktor
  aWerte[1,3]:=(aWerte[1,0]-aWerte[1,1])/aWerte[1,2];  //Maximale Anzahl der Möglichkeiten
    //2. Gang
  aWerte[2,0]:=6.00; //MaxWert
  aWerte[2,1]:=0.48; //MinWert
  aWerte[2,2]:=0.01; //Schrittfaktor
  aWerte[2,3]:=(aWerte[2,0]-aWerte[2,1])/aWerte[2,2];  //Maximale Anzahl der Möglichkeiten
    //3. Gang
  aWerte[3,0]:=6.00; //MaxWert
  aWerte[3,1]:=0.48; //MinWert
  aWerte[3,2]:=0.01; //Schrittfaktor
  aWerte[3,3]:=(aWerte[3,0]-aWerte[3,1])/aWerte[3,2];   //Maximale Anzahl der Möglichkeiten
    //4. Gang
  aWerte[4,0]:=6.00; //MaxWert
  aWerte[4,1]:=0.48; //MinWert
  aWerte[4,2]:=0.01; //Schrittfaktor
  aWerte[4,3]:=(aWerte[4,0]-aWerte[4,1])/aWerte[4,2];   //Maximale Anzahl der Möglichkeiten
    //5. Gang
  aWerte[5,0]:=6.00; //MaxWert
  aWerte[5,1]:=0.48; //MinWert
  aWerte[5,2]:=0.01; //Schrittfaktor
  aWerte[5,3]:=(aWerte[5,0]-aWerte[5,1])/aWerte[5,2];  //Maximale Anzahl der Möglichkeiten
    //6. Gang
  aWerte[6,0]:=6.00; //MaxWert
  aWerte[6,1]:=0.48; //MinWert
  aWerte[6,2]:=0.01; //Schrittfaktor
  aWerte[6,3]:=(aWerte[6,0]-aWerte[6,1])/aWerte[6,2];  //Maximale Anzahl der Möglichkeiten
 
 
  Ergebnis:=400;
  memo1.Clear;
  for I:=0 to Round(aWerte[0,3]) do   //Achsübersetzung
      begin
        for j:=0 to Round(aWerte[1,3]) do  //1. Gang
            begin
              for K:=0 to Round(aWerte[2,3]) do  //2. Gang
                  begin
                    if k>j then break;
                    for l:=0 to Round(aWerte[3,3]) do  //3. Gang
                        begin
                          if l>k then break;
                          for m:=0  to Round(aWerte[4,3]) do  //4. Gang
                              begin
                                if m>l then break;
                                for n:=0 to Round(aWerte[5,3]) do //5. Gang
                                    begin
                                         if n>m then break;
                                         for o:=0 to Round(aWerte[6,3]) do   //6. Gang
                                          begin
                                            if o>n then break;
 
					    //Berechnung durch einstetzen der Koeffizienten in die Formel
                                            vmax:=aFormel[0]*(umw(i,aWerte[0,1],aWerte[0,2]))+aFormel[1]*(umw(j,aWerte[1,1],aWerte[1,2]))+aFormel[2]*(umw(k,aWerte[2,1],aWerte[2,2]))+aFormel[3]*(umw(l,aWerte[3,1],aWerte[3,2]))+aFormel[4]*   
  (umw(m,aWerte[4,1],aWerte[4,2]))+aFormel[5]*(umw(n,aWerte[5,1],aWerte[5,2]))+aFormel[6]*(umw(o,aWerte[5,1],aWerte[5,2]));
 
					    //speichern der Koeffizienten
					    aergebnis[0]:=aFormel[0]*(umw(i,aWerte[0,1],aWerte[0,2]));//Achsübersetzung
					    aergebnis[1]:=aFormel[1]*(umw(j,aWerte[1,1],aWerte[1,2]));//1. Gang
					    aergebnis[2]:=aFormel[2]*(umw(k,aWerte[2,1],aWerte[2,2]));//2. Gang
					    aergebnis[3]:=aFormel[3]*(umw(l,aWerte[3,1],aWerte[3,2]));//3. Gang
					    aergebnis[4]:=aFormel[4]*(umw(m,aWerte[4,1],aWerte[4,2]));//4. Gang
					    aergebnis[5]:=aFormel[5]*(umw(m,aWerte[5,1],aWerte[5,2]));//5. Gang
					    aergebnis[6]:=aFormel[6]*(umw(m,aWerte[6,1],aWerte[6,2]));//6. Gang
 
					    //sinnloses ausgeben damit man sieht das sich was tut
					    memo1.lines.add('Max. Endgeschwindigkeit: '+FloatToStr(Vmax) +' AchsÜ '+ FloattoStr(aErgebnis[0])+' 1.G '+FloatToStr(aErgebnis[1])+' 2.G '+FloatToStr(aErgebnis[2])+' 3.G '+FloatToStr(aErgebnis[3])+' 4.G '+FloatToStr(aErgebnis[4])+' 5.G '+FloatToStr(aErgebnis[5])+' 6.G '+FloatToStr(aErgebnis[6]));                                                                                
 
 					    //prüfen ob ein besseres Ergebnis (Startwert 400) gefunden wurde
					    if Vmax>Ergebnis then
						begin
						   str.add('FloatToStr(Vmax) +' '+ FloattoStr(aErgebnis[0])+' '+FloatToStr(aErgebnis[1])+' '+FloatToStr(aErgebnis[2])+' '+FloatToStr(aErgebnis[3])+' '+FloatToStr(aErgebnis[4])+' '+FloatToStr(aErgebnis[5])+' '+FloatToStr(aErgebnis[6]));
                                            	   memo3.lines.add('Max. Endgeschwindigkeit: '+FloatToStr(Vmax) +' AchsÜ '+ FloattoStr(aErgebnis[0])+' 1.G '+FloatToStr(aErgebnis[1])+' 2.G '+FloatToStr(aErgebnis[2])+' 3.G '+FloatToStr(aErgebnis[3])+' 4.G '+FloatToStr(aErgebnis[4])+' 5.G '+FloatToStr(aErgebnis[5])+' 6.G '+FloatToStr(aErgebnis[6]));
						   Ergebnis:=vmax;	
						end;
 
                                            end;
                                          end;
                                    end;
                              end;
                        end;
                  end;
            end;
      end;
str.savetofile('vmax.txt');
str.free;
end;
 
function TForm1.umw(tick, minw, sf: real): real;
begin
  result:=tick*sf+minw;
end;

wp_xyz
Beiträge: 5146
Registriert: Fr 8. Apr 2011, 09:01

Re: Funktionswerte durch Schleifen ermitteln, ander Ansatz?

Beitrag von wp_xyz »

Die Extremwertsuche ist kein triviales Problem. Wenn du's "richtig" machen willst, musst du dich z.B. durch die Numerical Recipes durcharbeiten. Dieser Link zeigt den Algorithmus, durch konsequentes "Bergab-Laufen" das Minimum einer Funktion von "beliebig" vielen Variablen zu suchen (Kap 10.4), inkl. Fortran-Code - es gibt aber irgendwo auch eine Pascal-Ausgabe. Deine Maximum-Suche kannst du durch Multplikation der Funktion mit -1 in eine Minimum-Suche umwandeln. Allerdings musst du aufpassen, dass der Algorithmus nicht nur ein lokales Minimum findet.

Hartkern
Beiträge: 69
Registriert: Sa 5. Dez 2015, 20:03
OS, Lazarus, FPC: Win10 IDE 1.6
CPU-Target: 64Bit
Wohnort: Leipzig

Re: Funktionswerte durch Schleifen ermitteln, ander Ansatz?

Beitrag von Hartkern »

Das wird dann wohl nen halbes Mathestudium :shock: :D

Danke für den Link...!!! Und nebenbei noch ne Bachelorarbeit schreiben wird interessant.

Hat jemand ne Idee wie lange meine Variante brauch?

wp_xyz
Beiträge: 5146
Registriert: Fr 8. Apr 2011, 09:01

Re: Funktionswerte durch Schleifen ermitteln, ander Ansatz?

Beitrag von wp_xyz »

Hartkern hat geschrieben:Hat jemand ne Idee wie lange meine Variante brauch?
Nö, probier's halt aus.

Antworten